标准WPF选项卡控件中是否有“选定的选项卡更改事件”


96

在WPF中,是否有一个事件可以用来确定TabControl所选标签的更改时间?

我尝试使用,TabControl.SelectionChanged但是当选项卡中的孩子的选择被更改时,它会被解雇很多次。

Answers:


121

我将此绑定到处理程序中以使其工作:

void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.Source is TabControl)
    {
      //do work when tab is changed
    }
}

2
我以为这没用,但后来我意识到我要检查的sendere.Source
Guillermo Ruffino,2013年

4
或只是添加e.Handled = true以防止其冒泡
Brock Hensley

77

如果x:Name将每个属性设置TabItem为:

<TabControl x:Name="MyTab" SelectionChanged="TabControl_SelectionChanged">
    <TabItem x:Name="MyTabItem1" Header="One"/>
    <TabItem x:Name="MyTabItem2" Header="2"/>
    <TabItem x:Name="MyTabItem3" Header="Three"/>
</TabControl>

然后,您可以TabItem在活动中访问每个:

private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (MyTabItem1.IsSelected)
    // do your stuff
    if (MyTabItem2.IsSelected)
    // do your stuff
    if (MyTabItem3.IsSelected)
    // do your stuff
}

50

如果您只想在选择选项卡时发生事件,这是正确的方法:

<TabControl>
    <TabItem Selector.Selected="OnTabSelected" />
    <TabItem Selector.Selected="OnTabSelected" />
    <TabItem Selector.Selected="OnTabSelected" />
    <!-- You can also catch the unselected event -->
    <TabItem Selector.Unselected="OnTabUnSelected" />
</TabControl>

在你的代码中

    private void OnTabSelected(object sender, RoutedEventArgs e)
    {
        var tab = sender as TabItem;
        if (tab != null)
        {
            // this tab is selected!
        }
    }

不幸的是,尽管看起来很不错,但我没有在xaml中使用Selected属性,而只是使用IsSelected。抱歉。
PHenry 2014年

我站得住了。。。DOH!当我尝试在VS中键入以上内容时,它给了我红色的曲线,因此我认为这是错误的。但是,当我将其粘贴时,只是盲目地按F5键,令我惊讶的是,它起作用了。H ?! 为什么以这种方式工作?
PHenry 2014年

如何在代码而不是xaml中访问“ Selector.Selected”事件
Ahmed_Faraz

15

您仍然可以使用该事件。只需检查sender参数是您真正关心的控件即可,如果是,请运行事件代码。


4

生成的事件会冒泡直到处理完毕。

不论。中的更改如何,下面的xaml部分都会在更改了所选项目ui_Tab_Changed后触发。ui_A_ChangedListViewTabItemTabControl

<TabControl SelectionChanged="ui_Tab_Changed">
  <TabItem>
    <ListView SelectionChanged="ui_A_Changed" />
  </TabItem>
  <TabItem>
    <ListView SelectionChanged="ui_B_Changed" />
  </TabItem>
</TabControl>

我们需要在ui_A_Changed(和ui_B_Changed,等等)中使用事件:

private void ui_A_Changed(object sender, SelectionChangedEventArgs e) {
  // do what you need to do
  ...
  // then consume the event
  e.Handled = true;
}

2

那是正确的事件。也许接线不正确?

<TabControl SelectionChanged="TabControl_SelectionChanged">
    <TabItem Header="One"/>
    <TabItem Header="2"/>
    <TabItem Header="Three"/>
</TabControl>

在后面的代码中...

private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    int i = 34;
}

如果我在i = 34行上设置了一个断点,则仅当我更改选项卡时它才会中断,即使这些选项卡具有子元素并且选中了其中之一。


在选项卡中放置一个网格,如果未在该选项卡到达事件之前对其进行处理,则选择一个网格行将冒泡直至该选项卡中的所选事件。
保罗·斯威兹

2

这段代码似乎有效:

    private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        TabItem selectedTab = e.AddedItems[0] as TabItem;  // Gets selected tab

        if (selectedTab.Name == "Tab1")
        {
            // Do work Tab1
        }
        else if (selectedTab.Name == "Tab2")
        {
            // Do work Tab2
        }
    }

1

如果您使用的是MVVM模式,则使用事件处理程序很不方便(并破坏了模式)。相反,您可以绑定每个单独的TabItem的Selector.IsSelected属性到视图模型中的依赖项属性,然后处理PropertyChanged事件处理程序。这样一来,您就可以准确地知道根据哪个标签选择/取消选择了哪个标签PropertyName并且每个选项卡都有一个特殊的处理程序。

例: MainView.xaml

<TabControl>
 <TabItem Header="My tab 1" Selector.IsSelected="{Binding IsMyTab1Selected}"> ... </TabItem>
 <TabItem Header="My tab 2" Selector.IsSelected="{Binding IsMyTab2Selected}"> ... </TabItem>
</TabControl>

例: MainViewModel.cs

public bool IsMyTab1Selected {
 get { return (bool)GetValue(IsMyTab1SelectedProperty); }
 set { SetValue(IsMyTab1SelectedProperty, value); }
}
public static readonly DependencyProperty IsMyTab1SelectedProperty =
DependencyProperty.Register("IsMyTab1Selected", typeof(bool), typeof(MainViewModel), new PropertyMetadata(true, new PropertyChangedCallback(MyPropertyChanged)));

public bool IsMyTab2Selected {
 get { return (bool)GetValue(IsMyTab2SelectedProperty); }
 set { SetValue(IsMyTab2SelectedProperty, value); }
}
public static readonly DependencyProperty IsMyTab2SelectedProperty =
DependencyProperty.Register("IsMyTab2Selected", typeof(bool), typeof(MainViewModel), new PropertyMetadata(false, new PropertyChangedCallback(MyPropertyChanged)));

private void MyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
 if (e.Property.Name == "IsMyTab1Selected") {
  // stuff to do
 } else if (e.Property.Name == "IsMyTab2Selected") {
  // stuff to do
 }
}

如果你MainViewModelINotifyPropertyChanged,而不是DependencyObject,请改用:

例: MainViewModel.cs

public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) {
 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

public MainViewModel() {
 PropertyChanged += handlePropertyChanged;
}

public bool IsMyTab1Selected {
 get { return _IsMyTab1Selected ; }
 set {
  if (value != _IsMyTab1Selected ) {
   _IsMyTab1Selected = value;
   OnPropertyChanged("IsMyTab1Selected ");
  }
 }
}
private bool _IsMyTab1Selected = false;

public bool IsMyTab2Selected {
 get { return _IsMyTab2Selected ; }
 set {
  if (value != _IsMyTab2Selected ) {
   _IsMyTab2Selected = value;
   OnPropertyChanged("IsMyTab2Selected ");
  }
 }
}
private bool _IsMyTab2Selected = false;

private void handlePropertyChanged(object sender, PropertyChangedEventArgs e) {
 if (e.PropertyName == "IsMyTab1Selected") {
  // stuff to do
 } else if (e.PropertyName == "IsMyTab2Selected") {
  // stuff to do
 }
}

-1

如果有人使用WPF现代UI,则不能使用OnTabSelected事件。但可以使用SelectedSourceChanged事件。

像这样

<mui:ModernTab Layout="Tab" SelectedSourceChanged="ModernTab_SelectedSourceChanged" Background="Blue" AllowDrop="True" Name="tabcontroller" >

C#代码是

private void ModernTab_SelectedSourceChanged(object sender, SourceEventArgs e)
    {
          var links = ((ModernTab)sender).Links;

          var link = this.tabcontroller.Links.FirstOrDefault(l => l.Source == e.Source);

          if (link != null) {
              var index = this.tabcontroller.Links.IndexOf(link);
              MessageBox.Show(index.ToString());
          }            
    }

3
使用第三方参数从来都不是解决方案,应极力劝阻。
史蒂文·博尔赫斯

@steven我是为WPF MUI编写的,这也不是问题的答案。但这可能是wpf mui用户的答案。这就是为什么我将其作为答案。谢谢
Sandun Harshana '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.