在WPF中,有没有一种事件可以用来确定TabControl
所选标签页发生更改的情况?
我已经尝试使用TabControl.SelectionChanged
,但是当标签页内的子项选择发生更改时,它被触发了很多次。
在WPF中,有没有一种事件可以用来确定TabControl
所选标签页发生更改的情况?
我已经尝试使用TabControl.SelectionChanged
,但是当标签页内的子项选择发生更改时,它被触发了很多次。
您需要检查事件的源以隔离您正在寻找的最外层TabControl
。
我在处理程序中尝试了这个方法,使其正常工作:
void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.Source is TabControl)
{
// do work when tab is changed
}
}
如果您将 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
}
如果你只想在选定选项卡时触发某个事件,那么这是正确的方式:
<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!
}
}
someTabItem.AddHandler(Selector.SelectedEvent, ....
- Ben Voigt你仍然可以使用那个事件。只需检查发送器参数是否是你实际关心的控件,如果是,则运行事件代码。
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>
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
}
}
生成的事件会一直冒泡到处理它的位置。
以下的xaml部分在选中ListView
中的项更改时触发 ui_A_Changed
后立即触发ui_Tab_Changed
,而不管 TabControl
中的 TabItem
是否更改。
<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;
}
那就是正确的事件。也许它没有正确连接?
<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 这一行设置断点,那么它只会在我切换标签页时才中断,即使标签页有子元素并且其中一个被选中。
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
}
}
如果你正在做mvvm,你也可以通过绑定TabControl的SelectedIndex属性来实现这一点:
<TabControl SelectedIndex="{Binding SelectedTabIndex}"
当属性更新时,您将收到更改的通知,并立即获得所选TabItem的索引。
如果有人使用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());
}
}
sender
而不是e.Source
。 - Guillermo Ruffinoe.Handled = true
来防止事件冒泡。 - Brock Hensley