从子UserControl更改父窗口TabControl的选项卡

从子UserControl更改父窗口TabControl的选项卡

问题描述:

我有一个父窗口其中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}" /> 

你可以做一些事情,是有点 “哈克”,而是非常简单。这将是少哈克如果每个用户控件的不会有它自己的视图模型(不明白为什么这是必要的。

不管怎么说,我们的目标就是进入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

    您可以尝试添加到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}">