我有一个这样的tabcontrol:
<TabControl>
<local:TabItem x:Name="son" Header="son">
<local_son:SonView />
</local:TabItem>
<local:TabItem x:Name="daughter" Header="daughter">
<local_daughter:DaughterView />
</local:TabItem>
</TabControl>DaughterView里有一个按钮,我想点击这个按钮切换到子页签。我的问题是,如何才能在DaughterView中访问tab _ in _in_tab?
提前谢谢你!
发布于 2015-08-14 06:28:35
在标签中有一个按钮切换到另一个标签看起来有点奇怪。我认为那应该是一个工具栏按钮或类似的东西。即在翼片的外部。但是如果你坚持:)..。我会使用messenger / event aggregator模式,发布一个事件,并让视图订阅并切换选项卡。我不会让子视图自己去做。
发布于 2015-08-14 09:00:40
您需要将"SelectedIndex“绑定到视图模型中的属性。我个人喜欢保持类型安全并且能够进行单元测试,所以当我需要在代码中操作TabControls时,我通常首先为每个选项卡声明一个枚举:
public enum MyTabs : int
{
[Description("Tab 1")]
Tab1,
[Description("Tab 2")]
Tab2,
[Description("Tab 3")]
Tab3
}description属性是我希望显示在选项卡头中的文本,稍后将对此进行详细介绍。我的视图模型包含一个MyTabs类型的成员,每当用户单击选项卡时都会更新该成员,我也可以通过代码手动设置它:
public class MyViewModel : ViewModelBase
{
private MyTabs _CurrentTab;
public MyTabs CurrentTab
{
get { return this._CurrentTab;}
set { this._CurrentTab = value; RaisePropertyChanged(() => this.CurrentTab); }
}
}现在,您需要将TabControl绑定到此属性:
<TabControl
ItemsSource="{Binding Source={StaticResource MyTabs}}"
SelectedIndex="{Binding CurrentTab, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Header" Value="{Binding Path=., Converter={StaticResource EnumDescriptionConverter}}" />
</Style>
</TabControl.Resources>
</TabControl>不幸的是,WPF绑定不够智能,无法处理整数枚举,所以我还使用了一个转换器在枚举和整数之间进行转换:
public class EnumToIntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (int)value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Enum.ToObject(targetType, value);
}
}在here...first上还有一些其他的事情,你会注意到,我实际上并没有在任何地方声明TabItems。这是因为我是从枚举值本身自动生成它们的;如果我向MyTab枚举添加一个新值,那么它的一个选项卡就会神奇地出现!在本例中,我使用键"MyTabs“绑定到一个静态资源,这是一个枚举枚举中的值的ObjectDataProvider:
<ObjectDataProvider x:Key="MyTabs" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:MyTabs"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>这就提出了一个问题:选项卡如何知道在其标题和tabitem内容区域中显示什么内容。标头使用枚举中声明的“EnumDescriptionConverter”属性,描述的代码在another page on this site上。为了指定每个页面的内容,我为我的每个枚举值创建了一个ControlTemplate,并将其键控到枚举值本身。然后使用数据模板为每个选项卡选择适当的数据模板:
<Window.Resources>
<ControlTemplate x:Key="{x:Static local:MyTabs.Tab1}">
<TextBlock Text="This is the first tab" />
</ControlTemplate>
<ControlTemplate x:Key="{x:Static local:MyTabs.Tab2}">
<TextBlock Text="This is the second tab" />
</ControlTemplate>
<ControlTemplate x:Key="{x:Static local:MyTabs.Tab3}">
<TextBlock Text="This is the third tab" />
</ControlTemplate>
<DataTemplate DataType="{x:Type local:MyTabs}">
<ContentControl>
<ContentControl.Template>
<MultiBinding Converter="{StaticResource ResourceKey=BindingToResourceConverter}">
<Binding RelativeSource="{RelativeSource AncestorType={x:Type Window}}" Path="Resources" />
<Binding />
</MultiBinding>
</ContentControl.Template>
</ContentControl>
</DataTemplate>
</Window.Resources>最后一块拼图是BindingToResourceConverter,它只接受一个绑定(即一个枚举值),并使用它来查找适当的ControlTemplate:
public class BindingToResourceConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (values[0] as ResourceDictionary)[values[1]];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}就是这样!每次我想要向枚举添加新页面时,我只需向其相应的枚举添加值,并为该值创建一个ContentControl键。其他一切都是自动发生的,最棒的是它既是类型安全的,又是单元可测试的。
https://stackoverflow.com/questions/31999068
复制相似问题