标准WPF选项卡控件中是否有Selected Tab Changed事件

问题描述 投票:0回答:10

在 WPF 中,是否有一个事件可用于确定

TabControl
的选定选项卡何时更改?

我试过使用

TabControl.SelectionChanged
但是当孩子在选项卡中的选择发生变化时它会被解雇很多次。

wpf events tabcontrol
10个回答
141
投票

您需要检查事件的来源以隔离您正在寻找的最外层

TabControl

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

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

92
投票

如果将

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
}

60
投票

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

<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!
        }
    }

15
投票

你仍然可以使用那个事件。只需检查 sender 参数是否是您真正关心的控件,如果是,则运行事件代码。


8
投票

如果您使用的是 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
 }
}

如果你的

MainViewModel
INotifyPropertyChanged
而不是
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
 }
}

4
投票

生成的事件冒泡,直到它被处理。

下面的 xaml 部分在

ui_Tab_Changed
之后触发
ui_A_Changed
ListView
中选择的项目发生变化时,无论
TabItem
TabControl
中的变化。

<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;
}

3
投票

这是正确的事件。也许它没有正确连接?

<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
        }
    }

0
投票

如果你正在做 mvvm,你也可以通过绑定到 TabControl 的 SelectedIndex 属性来做到这一点:

<TabControl SelectedIndex="{Binding SelectedTabIndex}"

然后当 Property 更新时,您会收到更改通知,并且您会立即获得所选 TabItem 的索引。


-2
投票

如果有人使用 WPF Modern 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());
          }            
    }
© www.soinside.com 2019 - 2024. All rights reserved.