2014-09-03 1 views
1

MVVM을 사용하는 WPF에서 사용자가 탭을 변경하면 일부 코드가 쉽게 실행됩니다. WPF SelectedIndex가 아닌 SelectedValue 탭을 기반으로 한 MVVM 실행 코드

<TabControl Margin="0 5 5 5" Background="#66F9F9F9" SelectedIndex="{Binding TabIndex}"> 

그리고 다음 뷰 모델에

:

private int _tabIndex; 
public int TabIndex 
{ 
    get { return _tabIndex; } 
    set 
    { 
     if(_tabIndex != value) 
     { 
      _tabIndex = value; 
      OnPropertyChanged("TabIndex"); 

      if(value == 1) 
      { 
       //do something 
      } 
     } 
    } 
} 

하지만 이것에 막연하게 불편 해요. 나중에 다른 개발자가 발생하고 "1"위치에 다른 탭을 추가하면 어떻게 될까요? 응용 프로그램에 중요한 코드 (이것이있는)라면 상황은 훌륭하게 나빠질 것입니다.

단위 테스트를 통해 위험을 최소화 할 수 있습니다. 그러나 그것은 나에게 궁금해하게했다 : 이것은 나쁜 연습으로 간주 되는가? 그리고 당신이 int가 아닌 문자열로 탭을 참조 할 수있게하는 방법이 있습니까? SelectedValue 속성에 바인딩으로 noodling을 시도했지만 탭이 변경되었을 때 아무런 반응이 없었습니다.

+1

나는 그것에 대해서도 걱정할 것이다. 또 다른 경고 플래그는 viewmodel에 탭 인덱스가있는 것은 viewmodel에 뷰 기반 논리가 있음을 의미하며 뷰와 로직의 분리를 파괴합니다. 탭을 변경할 때 무엇을해야합니까? – sondergard

+0

@sondergard 초기 탭을 사용하면 새 데이터가 사용되는 두 번째 탭으로 전환하기 전에 데이터베이스에 생성 및 저장해야하는 많은 개체를 선택할 수 있습니다. –

답변

1

모든 컬렉션 컨트롤과 마찬가지로 선택한 항목을 유지 관리하는 가장 좋은 방법은 SelectedItem 속성을 사용하는 것입니다. 관련 데이터 유형의 속성을 데이터로 TabControl.SelectedItem property에 바인딩하면 어떤 탭이 선택되었는지 알 수 있고 뷰 모델에서 다른 탭을 선택할 수 있습니다. 다음, 당신은을 정의하는 것을 알아야한다 당신이 시도 할 경우

<TabControl ItemsSource="{Binding YourDataItems}" SelectedItem="{Binding YourItem}" /> 

:

이 방법의 유일한 문제는 당신은 또한 TabItem의를 설정 TabControl.ItemsSource 속성을 사용해야한다는 것입니다 TabItem 약간 혼란 스러울 수 있습니다. 도움이 필요하면 How to bind items of a TabControl to an observable collection in wpf? 질문의 대답을 참조하십시오.

1

TabItem에 대해 동작을 수행하고 IsSelected 종속성 속성의 변경 내용을 수신 한 다음 탭을 선택하면 명령을 실행할 수 있습니다. 이는 뷰 모델에서 다른 명령을 호출하는 여러 탭으로 확장 될 수 있습니다. 또한 선택적 상황에 대한 명령 매개 변수를 제공 할 수 있습니다 :

class TabSelectedBehavior : Behavior<TabItem> 
{ 
    public static readonly DependencyProperty SelectedCommandProperty = DependencyProperty.Register("SelectedCommand", typeof(ICommand), typeof(TabSelectedBehavior)); 

    public ICommand SelectedCommand 
    { 
     get { return (ICommand)GetValue(SelectedCommandProperty); } 
     set { SetValue(SelectedCommandProperty, value); } 
    } 

    private EventHandler _selectedHandler; 

    protected override void OnAttached() 
    { 
     DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(TabItem.IsSelectedProperty, typeof(TabItem)); 
     if (dpd != null) 
     { 
      _selectedHandler = new EventHandler(AssociatedObject_SelectedChanged); 
      dpd.AddValueChanged(AssociatedObject, _selectedHandler); 
     } 

     base.OnAttached(); 
    } 

    protected override void OnDetaching() 
    { 
     DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(TabItem.IsSelectedProperty, typeof(TabItem)); 
     if (dpd != null && _selectedHandler != null) 
     { 
      dpd.RemoveValueChanged(AssociatedObject, _selectedHandler); 
     } 

     base.OnDetaching(); 
    } 

    void AssociatedObject_SelectedChanged(object sender, EventArgs e) 
    { 
     if (AssociatedObject.IsSelected) 
     { 
      if (SelectedCommand != null) 
      { 
       SelectedCommand.Execute(null); 
      } 
     } 
    } 
} 

XAML

<TabControl> 
    <TabItem Header="TabItem1"> 
      <i:Interaction.Behaviors> 
       <local:TabSelectedBehavior SelectedCommand="{Binding TabSelectedCommand}"/> 
      </i:Interaction.Behaviors> 
     </TabItem> 
     <TabItem Header="TabItem2"> 
    </TabItem> 
</TabControl> 

비슷한 방식으로 당신은 또한 명령에 인 selectionchanged 이벤트를 도는 TabControl에 대한 행동을 할 수있는, 선택한 TabItem의 Tag 객체를 명령 매개 변수로 전달합니다.