2017-10-16 140 views
0

我有一個父窗口其中TabControl。每個選項卡都包含與其關聯的UserControl。在我的UserControl之一中,我有一個按鈕。當我點擊按鈕時,我想要更改我父窗口中TabControl的選定選項卡。從子UserControl更改父窗口TabControl的選項卡

我正在使用MVVM模式,所以如果可能的話,我想在XAML中使用我的按鈕上的Command屬性。

例如:

<Button Content="Switch Tab" Command="{Binding SwitchTabCommand}" /> 

在此先感謝我的同胞的程序員!

父窗口視圖模型:

public class CoolViewModel : BaseViewModel 
{ 
    #region Properties 

    public ObservableCollection<ITabViewModel> Tabs { get; set; } 
    public ITabViewModel SelectedTab { get; set; } 

    #endregion 

    #region Constructor 

    public CoolViewModel() 
    { 
     Tabs = new ObservableCollection<ITabViewModel> 
     { 
      new VeryNiceViewModel(), 
      new VeryNiceViewModel() 
     }; 
    } 

    #endregion 
} 

這裏是片內的用戶控件的代碼:

public class VeryCoolViewModel : BaseViewModel, ITabViewModel 
{ 
    #region Properties 

    public ObservableCollection<Test> Tests { get; set; } 
    public Test currentSelection { get; set; } 
    public string TabHeader { get; set; } 

    #endregion 

    #region Commands 

    ICommand GoToOtherTab { get; set; } 

    #endregion 

    #region Constructor 

    public GabaritSelecteurViewModel() 
    { 
     Tests = new ObservableCollection<Test> 
     { 
      new Test { Title = "Title #1" }, 
      new Test { Title = "Title #2" }, 
      new Test { Title = "Title #3" }, 
      new Test { Title = "Title #4" }, 
      new Test { Title = "Title #5" } 
     }; 

     TabHeader = "Tests"; 

     GoToOtherTab = new RelayCommand(GoToTab, parameter => true); 
    } 

    #endregion 

    #region Methods 

    private void GoToTab(object parameter) 
    { 
     // I don't know how to tell to the 
     // parent window to go to the other tab... 
    } 

    #endregion 
} 

而這裏的XAML的用戶控件(也就是TabControl的內線):

<Button Content="Go to the other tab" Command="{Binding GoToOtherTab}" /> 

回答

0

你可以做一些事情,是有點 「哈克」,而是非常簡單。這將是少哈克如果每個用戶控件的不會有它自己的視圖模型(不明白爲什麼這是必要的。

不管怎麼說,我們的目標就是進入CoolViewModel。我們如何到達那裏?RelativeSource Binding總之,它使您能夠在不同的領域結合(除了你自己DataContext,這是在這個例子中,用戶控件)。

所以,我們知道你有一個TabControl它包含所有這些用戶控件的,我們知道,此TabControl的DataContextCoolViewModel。從withing用戶控件

public ICommand SwitchTabCommand {get;set;}

  • 綁定到它:

    <Button Content="Go to the other tab" Command= "{Binding RelativeSource={RelativeSource AncestorType={x:Type TabControl}}, Path=DataContext.SwitchTabCommand}" />

    1. CommandCoolViewModel這樣所以基本上你正在尋找最近的祖先TabControl,翻翻這DataContext的命令SwitchTabCommand

    +0

    如果有人能向我解釋如何創建有很好的格式化代碼塊,那將是巨大的。 – TomerAgmon1

    +0

    要創建代碼塊,請單擊{}圖標。 – Fred

    +0

    它的工作原理!非常感謝你! XAML設計器抱怨'Path = DataContext.SwitchToCommand',所以我不得不改變它:'Path = DataContext。(viewModels:CoolViewModel.SwitchToCommand),否則它會告訴我這一點:_Cannot無法解析數據上下文中的屬性'SwitchToCommand'類型爲object_。 – Fred

    0

    您可以嘗試添加到VeryCoolViewModel(您的UserControl VM)事件中:

    public class VeryCoolViewModel : BaseViewModel, ITabViewModel 
    { 
        #region Properties 
    
        public ObservableCollection<Test> Tests { get; set; } 
        public Test currentSelection { get; set; } 
        public string TabHeader { get; set; } 
    
        public delegate void ChangeSelectedTab(string tabName) 
        public event ChangeSelectedTab OnChangeSelectedTab 
        #endregion 
    
        #region Commands 
    
        ICommand GoToOtherTab { get; set; } 
    
        #endregion 
    
        #region Constructor 
    
        public GabaritSelecteurViewModel() 
        { 
         Tests = new ObservableCollection<Test> 
         { 
          new Test { Title = "Title #1" }, 
          new Test { Title = "Title #2" }, 
          new Test { Title = "Title #3" }, 
          new Test { Title = "Title #4" }, 
          new Test { Title = "Title #5" } 
         }; 
    
         TabHeader = "Tests"; 
    
         GoToOtherTab = new RelayCommand(GoToTab, parameter => true); 
        } 
    
        private void GoToTab(object parameter) 
        { 
          OnChangeSelectedTab?.Invoke((string)parameter); 
        } 
    } 
    

    和成父窗口VM在constuctor:

    public CoolViewModel() 
    { 
        Tabs = new ObservableCollection<ITabViewModel> 
        { 
         new VeryNiceViewModel(), 
         new VeryNiceViewModel() 
        }; 
        Tabs.ForEach(x =>{ 
         x.OnChangeSelectedTab += x_OnChangeSelectedTab 
        }); 
    
    } 
    
    private void x_OnChangeSelectedTab(string tabName) 
    { 
        // select from List of tabItems tabItem with name == tabName and then set propetry in this tabItem to true. 
        SomePropertyInParentViewModel = true; 
    } 
    

    ,並考慮:

    <TabItem x:Name="TabWhatYouNeed" IsSelected="{Binding SomePropertyInParentViewModel}">