从子 UserControl 更改父 Window TabControl 的选项卡
Change tab of parent Window TabControl from child UserControl
我有一个父级 window,里面有一个 TabControl
。每个选项卡都包含一个与之关联的 UserControl
。在我的 UserControl
之一中,我有一个按钮。当我单击该按钮时,我想更改父项 window 中 TabControl
的选定选项卡。
我正在使用 MVVM 模式,所以如果可能的话,我想在 XAML 中使用按钮上的命令 属性 来完成。
例如:
<Button Content="Switch Tab" Command="{Binding SwitchTabCommand}" />
在此先感谢各位程序员!
父window视图模型:
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
}
下面是选项卡中 UserControl 的代码:
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
}
这里是 UserControl(位于 TabControl 内)的 XAML:
<Button Content="Go to the other tab" Command="{Binding GoToOtherTab}" />
您可以尝试添加到 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);
}
}
并进入父 window 构造函数中的虚拟机:
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}">
您可以做一些 "hacky" 但非常简单的事情。如果您的每个 UserControl 都没有自己的 ViewModel(不太确定为什么需要这样做),那就不那么麻烦了。
无论如何,我们的目标是达到 CoolViewModel
。我们怎么去那里? RelativeSource Binding
。简而言之,它使您能够在不同的范围内进行绑定(除了您自己的 DataContext
,在此示例中为 UserControl)。
因此,我们知道您有一个 TabControl
,其中包含所有这些 UserControl,并且我们知道此 TabControl 的 DataContext
是 CoolViewModel
.
像这样把 Command
放在 CoolViewModel
中:
public ICommand SwitchTabCommand {get;set;}
使用 UserControl 绑定到它:
<Button Content="Go to the other tab" Command= "{Binding RelativeSource={RelativeSource AncestorType={x:Type TabControl}}, Path=DataContext.SwitchTabCommand}" />
所以基本上你正在寻找最近的祖先 TabControl
,通过它 DataContext
寻找命令 SwitchTabCommand
我有一个父级 window,里面有一个 TabControl
。每个选项卡都包含一个与之关联的 UserControl
。在我的 UserControl
之一中,我有一个按钮。当我单击该按钮时,我想更改父项 window 中 TabControl
的选定选项卡。
我正在使用 MVVM 模式,所以如果可能的话,我想在 XAML 中使用按钮上的命令 属性 来完成。
例如:
<Button Content="Switch Tab" Command="{Binding SwitchTabCommand}" />
在此先感谢各位程序员!
父window视图模型:
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
}
下面是选项卡中 UserControl 的代码:
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
}
这里是 UserControl(位于 TabControl 内)的 XAML:
<Button Content="Go to the other tab" Command="{Binding GoToOtherTab}" />
您可以尝试添加到 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);
}
}
并进入父 window 构造函数中的虚拟机:
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}">
您可以做一些 "hacky" 但非常简单的事情。如果您的每个 UserControl 都没有自己的 ViewModel(不太确定为什么需要这样做),那就不那么麻烦了。
无论如何,我们的目标是达到 CoolViewModel
。我们怎么去那里? RelativeSource Binding
。简而言之,它使您能够在不同的范围内进行绑定(除了您自己的 DataContext
,在此示例中为 UserControl)。
因此,我们知道您有一个 TabControl
,其中包含所有这些 UserControl,并且我们知道此 TabControl 的 DataContext
是 CoolViewModel
.
像这样把
Command
放在CoolViewModel
中:public ICommand SwitchTabCommand {get;set;}
使用 UserControl 绑定到它:
<Button Content="Go to the other tab" Command= "{Binding RelativeSource={RelativeSource AncestorType={x:Type TabControl}}, Path=DataContext.SwitchTabCommand}" />
所以基本上你正在寻找最近的祖先 TabControl
,通过它 DataContext
寻找命令 SwitchTabCommand