标准 WPF 选项卡控件中是否有选定的选项卡更改事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/772841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there Selected Tab Changed Event in the standard WPF Tab Control
提问by Jon Kragh
In WPF, is there an event that can be used to determine when a TabControl
's selected tab changes?
在 WPF 中,是否有可用于确定 aTabControl
的选定选项卡何时更改的事件?
I have tried using TabControl.SelectionChanged
but it is getting fired many times when a child's selection within a tab is changed.
我尝试过使用TabControl.SelectionChanged
但是当孩子在选项卡内更改时,它会被触发多次。
回答by Jon Kragh
I tied this in the handler to make it work:
我将它绑定在处理程序中以使其工作:
void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.Source is TabControl)
{
//do work when tab is changed
}
}
回答by unexpectedkas
If you set the x:Name
property to each TabItem
as:
如果您将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>
Then you can access to each TabItem
at the event:
然后您可以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
}
回答by MicBig
If you just want to have an event when a tab is selected, this is the correct way:
如果您只想在选择选项卡时有一个事件,这是正确的方法:
<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>
And in your code
在你的代码中
private void OnTabSelected(object sender, RoutedEventArgs e)
{
var tab = sender as TabItem;
if (tab != null)
{
// this tab is selected!
}
}
回答by Nidonocu
You could still use that event. Just check that the sender argument is the control you actually care about and if so, run the event code.
您仍然可以使用该事件。只需检查 sender 参数是否是您真正关心的控件,如果是,请运行事件代码。
回答by rolling
The event generated is bubbling up until it is handled.
生成的事件在被处理之前一直在冒泡。
This xaml portion below triggers ui_Tab_Changed
after ui_A_Changed
when the item selected in the ListView
changes, regardless of TabItem
change in the TabControl
.
下面触发器此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>
We need to consume the event in ui_A_Changed
(and ui_B_Changed
, and so on):
我们需要在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;
}
回答by Muad'Dib
That is the correct event. Maybe it's not wired up correctly?
那是正确的事件。也许它没有正确接线?
<TabControl SelectionChanged="TabControl_SelectionChanged">
<TabItem Header="One"/>
<TabItem Header="2"/>
<TabItem Header="Three"/>
</TabControl>
in the codebehind....
在代码隐藏中......
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
int i = 34;
}
if I set a breakpoint on the i = 34 line, it ONLY breaks when i change tabs, even when the tabs have child elements and one of them is selected.
如果我在 i = 34 行上设置断点,它只会在我更改选项卡时中断,即使选项卡具有子元素并且其中一个被选中。
回答by Mc_Topaz
This code seems to work:
这段代码似乎有效:
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
}
}
回答by Nikola Novak
If you're using the MVVM pattern then it is inconvenient (and breaks the pattern) to use the event handler. Instead, you can bind each individual TabItem's Selector.IsSelected
property to a dependency property in your viewmodel and then handle the PropertyChanged
event handler. That way you know exactly which tab was selected/deselected based on the PropertyName
and you have a special handler for each tab.
如果您使用的是 MVVM 模式,那么使用事件处理程序会很不方便(并且破坏了模式)。相反,您可以将每个单独的 TabItem 的Selector.IsSelected
属性绑定到视图模型中的依赖项属性,然后处理PropertyChanged
事件处理程序。这样您就可以确切地知道根据 选择/取消选择了哪个选项卡,PropertyName
并且每个选项卡都有一个特殊的处理程序。
Example: MainView.xaml
例子: MainView.xaml
<TabControl>
<TabItem Header="My tab 1" Selector.IsSelected="{Binding IsMyTab1Selected}"> ... </TabItem>
<TabItem Header="My tab 2" Selector.IsSelected="{Binding IsMyTab2Selected}"> ... </TabItem>
</TabControl>
Example: MainViewModel.cs
例子: 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
}
}
If your MainViewModel
is INotifyPropertyChanged
rather than DependencyObject
, then use this instead:
如果您的MainViewModel
isINotifyPropertyChanged
而不是DependencyObject
,则使用此代替:
Example: MainViewModel.cs
例子: 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
}
}
回答by Sandun Harshana
If anyone use WPF Modern UI,they cant use OnTabSelected event.but they can use SelectedSourceChanged event.
如果有人使用 WPF 现代 UI,他们不能使用 OnTabSelected 事件。但他们可以使用 SelectedSourceChanged 事件。
like this
像这样
<mui:ModernTab Layout="Tab" SelectedSourceChanged="ModernTab_SelectedSourceChanged" Background="Blue" AllowDrop="True" Name="tabcontroller" >
C# code is
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());
}
}