2014-09-03 34 views
1

在WPF WPF MVVM燒製代碼MVVM很容易,當用戶更改標籤火一些代碼。基於標籤的SelectedValue,而不是SelectedIndex的

<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來引用Tab?我試圖用綁定到SelectedValue屬性,但沒有什麼似乎在選項卡更改時發生。

+1

我也會關心這一點。另一個警告標誌是在視圖模型中有一個Tab索引,意味着視圖模型中存在基於視圖的邏輯,這打破了視圖和邏輯的分離。在更改標籤頁時需要完成什麼? – sondergard 2014-09-03 14:10:28

+0

@sondergard初始選項卡允許用戶選擇多個對象,這些對象需要在切換到使用新數據的第二個選項卡之前創建並保存到數據庫。 – 2014-09-03 14:21:17

回答

1

與所有集控,保持所選項目的最好方法是使用SelectedItem屬性。如果您的數據將相關數據類型的屬性綁定到TabControl.SelectedItem property,那麼您仍然可以知道選擇了哪個選項卡,並從視圖模型中選擇不同的選項卡。

用這種方法唯一的問題是,你還需要使用TabControl.ItemsSource屬性來設置TabItem S:如果你想嘗試這種

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

,那麼你應該知道,定義TabItem s可能有點混亂。請參閱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> 

以類似的方式,你也可以做一個行爲的TabControl的,果然SelectionChanged事件到命令,並傳遞所選TabItem的Tag對象作爲命令參數。

相關問題