在WPF中,是否存在可用於確定TabControl
選定選項卡更改時間的事件?標準WPF選項卡控件中是否存在「選定選項卡已更改事件」
我嘗試過使用TabControl.SelectionChanged
,但是當標籤中的孩子的選擇發生變化時,它會被多次觸發。
在WPF中,是否存在可用於確定TabControl
選定選項卡更改時間的事件?標準WPF選項卡控件中是否存在「選定選項卡已更改事件」
我嘗試過使用TabControl.SelectionChanged
,但是當標籤中的孩子的選擇發生變化時,它會被多次觸發。
我在處理此掛鉤,使其工作:
void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.Source is TabControl)
{
//do work when tab is changed
}
}
您仍然可以使用該事件。只需檢查發件人參數是否是您真正關心的控件,如果是,請運行事件代碼。
這是正確的事件。也許它沒有正確連接?
<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行設置一個斷點,它只有當我更改選項卡斷,即使標籤子元素和一個他們被選中。
生成的事件冒泡,直到它被處理。
下面此XAML部觸發ui_Tab_Changed
ui_A_Changed
後當在TabControl
在ListView
變化選擇,無論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
,等等):如果你的x:Name
屬性設置爲每個TabItem
作爲
private void ui_A_Changed(object sender, SelectionChangedEventArgs e) {
// do what you need to do
...
// then consume the event
e.Handled = true;
}
:
<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
}
此代碼似乎工作:
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
}
}
如果你只是想有一個事件當選擇一個標籤,這是正確的做法:
<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-03-28 21:05:38
如果有人使用WPF現代用戶界面,他們不能使用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());
}
}
如果你使用MVVM模式則是不方便的(並打破模式)使用事件處理程序。相反,您可以將每個單獨的TabItem的Selector.IsSelected
屬性綁定到viewmodel中的依賴項屬性,然後處理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
}
}
我認爲這是行不通的,但後來我意識到我檢查`sender`,而不是`e.Source` – 2013-04-30 19:46:59
或只需添加`e.Handled = TRUE`,以防止其向上冒泡 – 2013-09-04 12:43:14