在带有MVVM的WPF中,当用户更改选项卡时,很容易激发一些代码。
<TabControl Margin="0 5 5 5" Background="#66F9F9F9" SelectedIndex="{Binding TabIndex}">
然后在ViewModel中:
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
属性,但在更改选项卡时似乎什么也没发生。
您可以为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对象作为命令参数传递。
与所有集合控件一样,维护所选项的最佳方法是使用SelectedItem
属性。如果将相关数据类型的属性数据绑定到TabControl.SelectedItem
属性,则仍然可以判断选择了哪个选项卡,并从视图模型中选择不同的选项卡。
此方法的唯一问题是,您还需要使用TabControl.ItemsSource
属性来设置TabItem
s:
<TabControl ItemsSource="{Binding YourDataItems}" SelectedItem="{Binding YourItem}" />
如果您想尝试这样做,那么您应该知道定义TabItem
可能有点令人困惑。请参阅如何将TabControl的项绑定到wpf中的可观察集合?寻求帮助。