自定义TabItem属性(TabItem.Content和TabItem.Header)

时间:2015-08-23 22:20:15

标签: c# wpf inheritance casting

我试图从System.Windows.Controls.TabItem班级继承MyTabItem。问题是,原始TabItem具有通用object类型的属性:

public object Header;
public object Content;

我试图在不同类型的派生类中隐藏这些属性。

public class MyTabItem: TabItem
{
    public new MyTabHeader Header;
    public new MyTabContent Content;
}

这样,我可以在不进行类型转换的情况下访问MyTabItem.HeaderMyTabItem.Content

这个想法相当不错,代码编译正确。但是,当应用程序启动时,我看到空控件(没有报告错误)。当我删除这些行并使用基类属性时,它可以正常工作。

enter image description here

当然,我可以添加两个额外的属性,这些属性会在内部返回已投放的(MyTabHeader)Header(MyTabContent)Header,但这似乎有点多余。

我问是否有其他方法可以正确实现这些属性,因此它们实际上可以在我的应用程序中使用。

1 个答案:

答案 0 :(得分:4)

这完全违背了WPF的设计方式。您的XAML对象应该与数据松散绑定,在绝大多数情况下,您甚至不需要创建自定义控件。您正在这样做,然后尝试用您自己的类型安全版本替换成员,这意味着您的视图代码和视图逻辑代码不再分离,这将使您感到头疼赛道。

如果您需要动态标签,那么一种方法是首先声明一个表示您的页面的抽象类,并从中派生您的页面类型:

public interface IBasePage
{
    string Header { get; }
}

public class MyPageA : ViewModelBase, IBasePage
{
    public string Header { get { return "Page A"; } }
}

public class MyPageB : ViewModelBase, IBasePage
{
    public string Header { get {return "Page B";} }
}

public class MyPageC : ViewModelBase, IBasePage
{
    public string Header { get {return "Page C";} }
}

您的视图模型(应该将您的窗口DataContext设置为)应该包含您希望显示的选项卡式页面的集合:

public class MyViewModel : ViewModelBase
{
    private IEnumerable<IBasePage> _MyPages = new List<IBasePage>(){
        new MyPageA(),
        new MyPageB(),
        new MyPageC()
    };
    public IEnumerable<IBasePage> MyPages {get {return this._MyPages;}}
}

然后,XAML中的选项卡控件与此松散绑定,并且应该包含TabItem的样式(因此它知道要用于标题的文本等)和DataTemplates,以便它知道如何呈现每种页面类型你创造了:

<TabControl ItemsSource="{Binding MyPages}" SelectedItem="{Binding MyPages[0], Mode=OneTime}">
    <TabControl.Resources>

        <!-- TabItem style -->
        <Style TargetType="{x:Type TabItem}">
            <Setter Property="Header" Value="{Binding Header}" />
        </Style>

        <!-- Content templates -->
        <DataTemplate DataType="{x:Type local:MyPageA}">
            <TextBlock Text="This is page A" />
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:MyPageB}">
            <TextBlock Text="This is page B" />
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:MyPageC}">
            <TextBlock Text="This is page C" />
        </DataTemplate>

    </TabControl.Resources>
</TabControl>

最终结果是一个完全由数据驱动的常规选项卡控件,并且绑定到已经强类型的模型:

enter image description here