標準のWPFタブコントロールに選択されたタブ変更イベントはありますか


96

WPFで、TabControlの選択されたタブがいつ変更されるかを判断するために使用できるイベントはありますか?

使用してみましたTabControl.SelectionChangedが、タブ内の子の選択が変更されると何度も起動されます。

回答:


121

これを機能させるためにハンドラーでこれを結びました:

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

2
これは機能していないと思いましたが、sender代わりにチェックしていることに気付きましたe.Source
Guillermo Ruffino 2013

4
またはe.Handled = true、泡立ちを防ぐために追加します
Brock Hensley

77

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
}

50

タブが選択されたときにイベントを発生させたい場合は、これが正しい方法です。

<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で利用できません。IsSelectedだけです。ごめんなさい。
PHenry 2014年

私は修正されたスタンド....のようなものです。DOH!上記についてVSで入力しようとすると、赤い波線が表示されるので、間違っていると思いました。しかし、私がそれを切り取って貼り付け、盲目的にF5を押したとき、驚いたことに、IT WORKEDでした。えっ?なぜそれがそのように機能したのですか?
PHenry 2014年

xaml

15

そのイベントは引き続き使用できます。sender引数が実際に必要なコントロールであることを確認し、そうであればイベントコードを実行します。


4

生成されたイベントは、処理されるまで発生しています。

トリガー以下、このXAML部ui_Tab_Changedui_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;
}

2

それは正しい出来事です。多分それは正しく配線されていませんか?

<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行にブレークポイントを設定すると、タブに子要素があり、その1つが選択されている場合でも、タブを変更したときにのみブレークが発生します。


グリッドをタブに配置し、グリッド行を選択すると、そこに到達する前に処理されない場合、タブが選択されたイベントまでバブルアップします。
Paul Swetz

2

このコードは動作するようです:

    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

MVVMパターンを使用している場合、イベントハンドラーを使用するのは不便です(パターンを壊します)。代わりに、個々のTabItemの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>

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

あなたがいる場合MainViewModelINotifyPropertyChangedはなく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
 }
}

-1

WPFモダン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());
          }            
    }

3
サードパーティの引数を使用することは決して解決策ではないので、お勧めしません。
Steven Borges

@steven私はこれをWPF MUI用に作成しましたが、これも質問への回答ではありません。ありがとう
Sandun Harshana 16
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.