如何以编程方式更改选项卡控件的索引&状态(也许使用命令?)

时间:2009-12-04 23:53:02

标签: c# wpf command radio-button tabcontrol

我有一个WPF TabControl,其中包含许多TabItem个带有UserControl个孩子的内容,就像这样。

XAML:

<TabControl x:Name="tabsMain"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
            Grid.Row="0" Grid.RowSpan="3" Background="lightgray">
    <TabItem Width="100" Header="Profile" FontSize="16">
        <InfoControl:InfoTab x:Name="myInfo" />
    </TabItem>
    <TabItem Width="120" x:Name="Summary" Header="Summary"  FontSize="16">
        <SummaryControl:SummaryTab/>
    </TabItem>
</TabControl>

在其中一个UserControl中,让我们说InfoTab,我有一个Button。单击此Button后,我想将TabControl的索引更改为SummaryTab,然后在SummaryTab页面上选择一个单选按钮。

我的问题是,InfoTab用户控件无法访问包含上面显示的MainUserControl的{​​{1}}。我想出了一个改变TabControl的{​​{1}}的kludge,但这是一个非常难看的解决方案,我宁愿做一些更干净的事情。此外,我目前无法更改SummaryTab上的SelectedIndex

My Current C#hack:

TabControl

是否可以使用命令或依赖项属性来选择RadioButton和我想要的 Private void btnSummaryDetails_Click(object sender, RoutedEventArgs e) { TabControl tabControl = UIHelper.FindChild<TabControl>(Application.Current.MainWindow, "tabsMain"); tabControl.SelectedIndex = 7; } ?我还是WPF世界的新手,并希望了解更多相关信息。提前致谢。

有关我在上述C#中使用的SummaryTab定义,请参阅my post here

3 个答案:

答案 0 :(得分:1)

我想到了一个不需要太多改变的想法。

首先,向InfoTab类添加一个事件:

public event EventHandler SummaryButtonClicked;

然后通过将控制声明替换为:

来处理主窗体中的声明
<InfoControl:InfoTab x:Name="myInfo" SummaryButtonClicked="summaryButtonClicked" />

并为SummaryTab命名:

<SummaryControl:SummaryTab x:Name="summaryTab" />

然后在主窗体中添加事件处理程序:

void MainWindow_SummaryButtonClicked(object sender, EventArgs e)
{
    this.summaryTab.SelectRadioButton();
}

在SummaryTab类中添加一个方法来选择单选按钮。

public void SelectRadioButton()
{
    // TODO: something like
    myRadioButton.IsChecked = true;
}

答案 1 :(得分:1)

您可以使用WPF routed events来解决您的问题。路由事件使用WPF可视树将事件发送到父控件(冒泡)或向下发送到子控件(隧道),而不会过度耦合。我试着在下面给出一个简单的例子,因为我知道路线事件起初可能有点毛茸茸,但值得一试......

在主窗口中,定义路由事件并添加处理程序方法:

public partial class MainWindow : Window {

    public static RoutedEvent ClickedEvent = EventManager.RegisterRoutedEvent(
        "Clicked",
        RoutingStrategy.Bubble,
        typeof(RoutedEventHandler),
        typeof(MainWindow));

    public MainWindow() {
        InitializeComponent();

        this.AddHandler(MainWindow.ClickedEvent, new RoutedEventHandler(OnClickedEvent));
    }

    public void OnClickedEvent(object sender, RoutedEventArgs e) {
        // do your work here

    }
}

在按钮单击处理程序中,引发事件:

public partial class UserControl1 : UserControl {
    public UserControl1() {
        InitializeComponent();
    }

    private void button1_Click(object sender, RoutedEventArgs e) {

        // raise the event (gets bubbled up to the parent of the control)
        this.RaiseEvent(new RoutedEventArgs(MainWindow.ClickedEvent));

    }
}

下一步是将另一个事件沿着可视树进行隧道传输,让另一个用户控件监听它。

答案 2 :(得分:0)

我最后添加了一个公共方法,就像杰里米在他的帖子中所说的那样。简单但有效的解决方案。谢谢杰里米!

另一个关键的实现是,为了通过索引切换tabcontrol,我可以获得对主用户控件的引用,并将SelectedItem设置为TabItem本身,如下所示:

  Private void btnSummaryDetails_Click(object sender, RoutedEventArgs e)  
 {

    //HACK replace this with a command that toggles to a different tab instead of this tab reference
    MainUserControl mainUserControl = UIHelper.FindChild<MainUserControl>(Application.Current.MainWindow, "root");
    mainUserControl.tabsMain.SelectedItem = mainUserControl.Summary;

    mainUserControl.SummaryUserControl.SelectRadioButton();
  }

然后正如杰里米所说,我的解决方案就像:

public void SelectRadioButton()
{
    // TODO: something like
    myRadioButton.IsChecked = true;
}

我的XAML结构就像

// my main user control: 
<UserControl 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
...
x:Name="root"
>
<TabControl x:Name="tabsMain" ...> 
<TabItem x:Name="Summary" ... />
</TabControl>
</UserControl>

我认为Andrew Jackson的评论绝对有效 - 长期来看,我打算调查使用路由命令或路由事件来遍历可视树,但是现在我坚持使用这个“快速而肮脏”的解决方案,因为我们是不发货此产品。根据我的调查,路线事件对于这种情况可能有点过分。