首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义TabItem属性(TabItem.Content和TabItem.Header)

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

Stack Overflow用户
提问于 2015-08-23 22:20:15
回答 1查看 596关注 0票数 0

我正在尝试从MyTabItem类继承System.Windows.Controls.TabItem。问题是,原始TabItem具有泛型object类型的属性:

代码语言:javascript
复制
public object Header;
public object Content;

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

代码语言:javascript
复制
public class MyTabItem: TabItem
{
    public new MyTabHeader Header;
    public new MyTabContent Content;
}

通过这种方式,我可以访问MyTabItem.HeaderMyTabItem.Content,而无需类型转换。

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

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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-24 00:26:15

这与WPF的设计使用方式完全相反。您的XAML对象应该松散地绑定到数据,在绝大多数情况下,您甚至不需要创建自定义控件。事实上,您正在这样做,然后尝试用您自己的类型安全版本替换成员,这意味着您的视图代码和视图逻辑代码不再分开,这将给您带来一个令人头痛的世界。

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

代码语言:javascript
复制
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应该设置的内容)应该包含您希望显示的选项卡页面的集合:

代码语言:javascript
复制
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的样式,以便它知道如何呈现您创建的每一种页面类型:

代码语言:javascript
复制
<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>

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32172122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档