Có sự kiện thay đổi tab đã chọn trong Điều khiển tab WPF tiêu chuẩn không


96

Trong WPF, có sự kiện nào có thể được sử dụng để xác định thời điểm TabControltab đã chọn của một thay đổi không?

Tôi đã thử sử dụng TabControl.SelectionChangednhưng nó bị kích hoạt nhiều lần khi lựa chọn của trẻ trong tab bị thay đổi.

Câu trả lời:


121

Tôi đã buộc cái này trong trình xử lý để làm cho nó hoạt động:

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

2
Tôi nghĩ điều này đã không làm việc nhưng sau đó tôi nhận ra tôi đã kiểm tra senderthay vìe.Source
Guillermo Ruffino

4
hoặc chỉ cần thêm e.Handled = trueđể ngăn chặn nó từ bọt lên
Brock Hensley

77

Nếu bạn đặt thuộc x:Nametính cho từng loại TabItemlà:

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

Sau đó, bạn có thể truy cập vào từng cái TabItemtại sự kiện:

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
}

50

Nếu bạn chỉ muốn có một sự kiện khi một tab được chọn, thì đây là cách chính xác:

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

Và trong mã của bạn

    private void OnTabSelected(object sender, RoutedEventArgs e)
    {
        var tab = sender as TabItem;
        if (tab != null)
        {
            // this tab is selected!
        }
    }

Thật không may là nó trông đẹp như cái này, tôi không nhận được thuộc tính Selected có sẵn cho tôi trong xaml, chỉ là IsSelected. Lấy làm tiếc.
PHenry

Tôi đứng sửa .... loại. DOH! Khi tôi cố gắng gõ về phần trên trong VS, nó cho tôi những hình vuông màu đỏ, do đó tôi nghĩ nó đã sai. NHƯNG khi tôi cắt nó ra và chỉ F5 nó một cách mù quáng, trước sự ngạc nhiên của tôi, nó đã hoạt động. HUH?! Tại sao nó hoạt động theo cách đó?
PHenry

Làm cách nào để truy cập sự kiện "Selector.Selected" bằng mã thay vì xaml
Ahmed_Faraz

15

Bạn vẫn có thể sử dụng sự kiện đó. Chỉ cần kiểm tra xem đối số người gửi có phải là điều khiển bạn thực sự quan tâm hay không và nếu có, hãy chạy mã sự kiện.


4

Sự kiện được tạo ra sẽ sôi lên cho đến khi nó được xử lý.

Phần xaml bên dưới này sẽ kích hoạt ui_Tab_Changedsau ui_A_Changedkhi mục được chọn trong các ListViewthay đổi, bất kể TabItemthay đổi trong TabControl.

<TabControl SelectionChanged="ui_Tab_Changed">
  <TabItem>
    <ListView SelectionChanged="ui_A_Changed" />
  </TabItem>
  <TabItem>
    <ListView SelectionChanged="ui_B_Changed" />
  </TabItem>
</TabControl>

Chúng ta cần sử dụng sự kiện trong ui_A_Changed(và ui_B_Changed, v.v.):

private void ui_A_Changed(object sender, SelectionChangedEventArgs e) {
  // do what you need to do
  ...
  // then consume the event
  e.Handled = true;
}

2

Đó là sự kiện chính xác. Có lẽ nó không được lên dây chính xác?

<TabControl SelectionChanged="TabControl_SelectionChanged">
    <TabItem Header="One"/>
    <TabItem Header="2"/>
    <TabItem Header="Three"/>
</TabControl>

trong mật mã ...

private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    int i = 34;
}

nếu tôi đặt một điểm ngắt trên dòng i = 34, điểm này CHỈ ngắt khi tôi thay đổi các tab, ngay cả khi các tab có các phần tử con và một trong số chúng được chọn.


đặt một lưới trong tab, việc chọn một hàng lưới sẽ bong bóng lên sự kiện đã chọn tab nếu không được xử lý trước khi đến đó.
Paul Swetz

2

Mã này dường như hoạt động:

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

1

Nếu bạn đang sử dụng mẫu MVVM thì việc sử dụng trình xử lý sự kiện sẽ không thuận tiện (và phá vỡ mẫu). Thay vào đó, bạn có thể liên kết từng Selector.IsSelectedthuộc tính TabItem riêng lẻ với thuộc tính phụ thuộc trong mô hình xem của mình và sau đó xử lý PropertyChangedtrình xử lý sự kiện. Bằng cách đó, bạn biết chính xác tab nào đã được chọn / bỏ chọn dựa trên PropertyNamevà bạn có một trình xử lý đặc biệt cho mỗi tab.

Thí dụ: MainView.xaml

<TabControl>
 <TabItem Header="My tab 1" Selector.IsSelected="{Binding IsMyTab1Selected}"> ... </TabItem>
 <TabItem Header="My tab 2" Selector.IsSelected="{Binding IsMyTab2Selected}"> ... </TabItem>
</TabControl>

Thí dụ: 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
 }
}

Nếu không phải MainViewModellà của bạn , thì hãy sử dụng cái này để thay thế:INotifyPropertyChangedDependencyObject

Thí dụ: 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
 }
}

-1

Nếu bất kỳ ai sử dụng WPF Modern UI, họ không thể sử dụng sự kiện OnTabSelected. Nhưng họ có thể sử dụng sự kiện SelectedSourceChanged.

như thế này

<mui:ModernTab Layout="Tab" SelectedSourceChanged="ModernTab_SelectedSourceChanged" Background="Blue" AllowDrop="True" Name="tabcontroller" >

Mã C # là

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

3
Sử dụng các lập luận của bên thứ ba không bao giờ là một giải pháp và cần được khuyến khích.
Steven Borges

@steven Tôi đã viết điều này cho WPF MUI và đây không phải là câu trả lời cho câu hỏi. nhưng đây có thể là câu trả lời cho người dùng wpf mui. Đó là lý do tại sao tôi đặt đây là câu trả lời. cảm ơn bạn
Sandun Harshana 30/12/16
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.