ใน WPF มีเหตุการณ์ที่สามารถใช้เพื่อกำหนดเมื่อTabControl
แท็บที่เลือกเปลี่ยนไปหรือไม่?
ฉันได้ลองใช้แล้วTabControl.SelectionChanged
แต่มันถูกยิงหลายครั้งเมื่อมีการเปลี่ยนแปลงการเลือกของเด็กในแท็บ
ใน WPF มีเหตุการณ์ที่สามารถใช้เพื่อกำหนดเมื่อTabControl
แท็บที่เลือกเปลี่ยนไปหรือไม่?
ฉันได้ลองใช้แล้วTabControl.SelectionChanged
แต่มันถูกยิงหลายครั้งเมื่อมีการเปลี่ยนแปลงการเลือกของเด็กในแท็บ
คำตอบ:
ฉันผูกสิ่งนี้ไว้ในตัวจัดการเพื่อให้ใช้งานได้:
void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.Source is TabControl)
{
//do work when tab is changed
}
}
e.Handled = true
เพื่อป้องกันไม่ให้เดือด
หากคุณตั้งค่า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!
}
}
คุณยังคงใช้เหตุการณ์นั้นได้ เพียงตรวจสอบว่าอาร์กิวเมนต์ผู้ส่งเป็นตัวควบคุมที่คุณสนใจจริงหรือไม่และถ้าเป็นเช่นนั้นให้รันโค้ดเหตุการณ์
เหตุการณ์ที่สร้างขึ้นจะเดือดปุด ๆ จนกว่าจะจัดการได้
ส่วน 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;
}
นั่นคือเหตุการณ์ที่ถูกต้อง อาจจะไม่ได้ต่อสายอย่างถูกต้อง?
<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 มันจะแตกเฉพาะเมื่อฉันเปลี่ยนแท็บแม้ว่าแท็บนั้นจะมีองค์ประกอบย่อยและหนึ่งในนั้นถูกเลือก
หากคุณใช้รูปแบบ MVVM ไม่สะดวก (และแตกรูปแบบ) ที่จะใช้ตัวจัดการเหตุการณ์ แต่คุณสามารถผูกแต่ละSelector.IsSelected
คุณสมบัติของ TabItem กับคุณสมบัติการพึ่งพาใน 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
}
}
ดูเหมือนว่ารหัสนี้จะใช้งานได้:
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
}
}
หากใครใช้ 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