代码之家  ›  专栏  ›  技术社区  ›  CrimsonX

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

  •  1
  • CrimsonX  · 技术社区  · 15 年前

    我有一个WPF TabControl 其中包含一个数字 TabItem 带孩子 UserControl S,像这样。

    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>
    

    在其中一个 用户控制 S,让我们说, InfoTab ,我有一个 Button . 当这 纽扣 单击后,我想更改 选项卡控件 SummaryTab 并选择 概要标签 页。

    我的问题是 信息标签 用户控件无权访问 MainUserControl 其中包含 选项卡控件 如上所示。我发现了一个可以改变 SelectedIndex 选项卡控件 但这是一个非常丑陋的解决方案,我更愿意做一些更干净的事情。另外,我目前无法更改 RadioButton 在我的摘要选项卡上。

    我目前的C黑客:

      Private void btnSummaryDetails_Click(object sender, RoutedEventArgs e)
      {
        TabControl tabControl = UIHelper.FindChild<TabControl>(Application.Current.MainWindow, "tabsMain");
        tabControl.SelectedIndex = 7;
      } 
    

    是否可以使用命令或依赖项属性来选择 概要标签 我想要的 单选按钮 ?我对WPF世界还是个新手,很想了解更多。事先谢谢。

    my post here 对于 UIHelper 我在上面的C中使用的定义。

    3 回复  |  直到 14 年前
        1
  •  1
  •   Jeremy    15 年前

    一个想法浮现在脑海中,不需要太多的改变。

    首先,将事件添加到infotab类中:

    public event EventHandler SummaryButtonClicked;
    

    然后在主窗体中处理它,方法是将控制声明替换为:

    <InfoControl:InfoTab x:Name="myInfo" SummaryButtonClicked="summaryButtonClicked" />
    

    给你的摘要标签起个名字:

    <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;
    }
    
        2
  •  1
  •   Andrew Jackson    15 年前

    你可能会用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));
    
        }
    }
    

    下一步将是通过隧道将另一个事件传输到可视化树中,并让另一个用户控件监听它。

        3
  •  0
  •   CrimsonX    15 年前

    我最后添加了一个公共方法,正如杰里米在他的帖子中建议的那样。一个简单但有效的解决方案。谢谢杰瑞米!

    另一个关键实现是,为了按索引切换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的评论是绝对有效的——从长远来看,我计划调查使用路由命令或路由事件来遍历可视化树,但目前我坚持使用这种“快速而肮脏”的解决方案,因为我们不提供此产品。根据我的调查,对于这种情况,路由事件可能有点过分。