표준 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
— 기예르모 Ruffino

4
아니면 그냥 추가 e.Handled = true품어 것을 방지하기 위해
— 브록 헨슬리

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에서 사용할 수있는 Selected 속성을 얻지 못하고 IsSelected 만 사용할 수 있습니다. 죄송합니다.
— PHenry

나는 정정 당했다 .... 종류. DOH! VS에서 위의 내용을 입력하려고하면 빨간색 구불 구불 한 모양이 나타나서 잘못되었다고 생각했습니다. 그러나 내가 그것을 잘라 내고 붙여넣고 맹목적으로 F5를했을 때 놀랍게도 그것은 작동했습니다. 어?! 왜 그렇게 작동 했습니까?
— PHenry

xaml 대신 코드에서 "Selector.Selected"이벤트에 액세스하는 방법
— Ahmed_Faraz

15

해당 이벤트를 계속 사용할 수 있습니다. sender 인수가 실제로 관심있는 컨트롤인지 확인하고 그렇다면 이벤트 코드를 실행하십시오.


4

생성 된 이벤트는 처리 될 때까지 버블 링됩니다.

이 트리거 아래 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;
}

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 행에 중단 점을 설정하면 탭에 자식 요소가 있고 그중 하나가 선택되어 있어도 탭을 변경할 때만 중단됩니다.


탭에 그리드를 넣고 그리드 행을 선택하면 탭이 선택되기 전에 처리되지 않으면 탭이 선택된 이벤트까지 버블 링됩니다.
— 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
 }
}

귀하의 경우 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
 }
}

-1

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

3
제 3 자 인수를 사용하는 것은 결코 해결책이 아니므로 매우 권장하지 않습니다.
— 스티븐 보르헤스

@steven 나는 WPF MUI를 위해 이것을 썼고 이것은 질문에 대한 대답이 아니지만 이것은 wpf mui 사용자에 대한 대답이 될 수 있습니다. 감사합니다
— Sandun Harshana에게
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.