표준 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.