Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF选项卡项自定义内容模板_Wpf_Datatemplate_Tabcontrol_Tabitem - Fatal编程技术网

WPF选项卡项自定义内容模板

WPF选项卡项自定义内容模板,wpf,datatemplate,tabcontrol,tabitem,Wpf,Datatemplate,Tabcontrol,Tabitem,我已经尝试了一段时间了,在WindowForms中做起来很简单 我正在制作一个IRC客户端,将有许多选项卡,每个通道连接一个选项卡。 每个选项卡都需要显示一些内容,如用户列表、消息历史记录和主题 在WindowForms中,我只是继承了TabItem,添加了一些自定义属性和控件,然后就完成了 在WPF中,我在解决如何做到这一点上遇到了一些小问题 我已经尝试了很多方法,下面是我当前的方法,但是我无法让TextBox绑定到Topic属性 <Style TargetType="{x:Ty

我已经尝试了一段时间了,在WindowForms中做起来很简单

我正在制作一个IRC客户端,将有许多选项卡,每个通道连接一个选项卡。 每个选项卡都需要显示一些内容,如用户列表、消息历史记录和主题

在WindowForms中,我只是继承了TabItem,添加了一些自定义属性和控件,然后就完成了

在WPF中,我在解决如何做到这一点上遇到了一些小问题

我已经尝试了很多方法,下面是我当前的方法,但是我无法让TextBox绑定到Topic属性

    <Style TargetType="{x:Type t:IRCTabItem}" BasedOn="{StaticResource {x:Type TabItem}}" >
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="540" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <StackPanel Grid.Column="0">
                        <TextBox Text="{Binding Topic, RelativeSource={RelativeSource AncestorType={x:Type t:IRCTabItem}}}" />   
                    </StackPanel>
                </Grid>
            </DataTemplate>              
        </Setter.Value>
    </Setter>
</Style>

代码背后

 public class IRCTabItem : TabItem
    {
        static IRCTabItem()
        {
            //This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
            //This style is defined in themes\generic.xaml
            //DefaultStyleKeyProperty.OverrideMetadata(typeof(IRCTabItem),
             //   new FrameworkPropertyMetadata(typeof(IRCTabItem)));
        }

        public static readonly RoutedEvent CloseTabEvent =
            EventManager.RegisterRoutedEvent("CloseTab", RoutingStrategy.Bubble,
                typeof(RoutedEventHandler), typeof(IRCTabItem));

        public event RoutedEventHandler CloseTab
        {
            add { AddHandler(CloseTabEvent, value); }
            remove { RemoveHandler(CloseTabEvent, value); }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            Button closeButton = base.GetTemplateChild("PART_Close") as Button;
            if (closeButton != null)
                closeButton.Click += new System.Windows.RoutedEventHandler(closeButton_Click);
        }

        void closeButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            this.RaiseEvent(new RoutedEventArgs(CloseTabEvent, this));
        }

        public bool Closeable
        {
            get { return (bool)GetValue(CloseableProperty); }
            set { SetValue(CloseableProperty, value); }
        }
        public static readonly DependencyProperty CloseableProperty = DependencyProperty.Register("Closeable", typeof(bool), typeof(IRCTabItem), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));


        public List<String> UserList
        {
            get { return (List<string>)GetValue(UserListProperty); }
            set { SetValue(UserListProperty, value); }
        }
        public static readonly DependencyProperty UserListProperty = DependencyProperty.Register("UserList", typeof(List<String>), typeof(IRCTabItem), new FrameworkPropertyMetadata(new List<String>(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public String Topic
        {
            get { return (string)GetValue(TopicProperty); }
            set { SetValue(TopicProperty, value); }
        }
        public static readonly DependencyProperty TopicProperty = DependencyProperty.Register("Topic", typeof(String), typeof(IRCTabItem), new FrameworkPropertyMetadata("Not Connected", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public bool HasAlerts
        {
            get { return (bool)GetValue(HasAlertsProperty); }
            set { SetValue(HasAlertsProperty, value); }
        }
        public static readonly DependencyProperty HasAlertsProperty = DependencyProperty.Register("HasAlerts", typeof(bool), typeof(IRCTabItem), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));


    }
公共类IRCTabItem:TabItem
{
静态IRCTabItem()
{
//这个OverrideMetadata调用告诉系统这个元素想要提供一个不同于它的基类的样式。
//此样式在themes\generic.xaml中定义
//DefaultStyleKeyProperty.OverrideMetadata(typeof(IRCTabItem)),
//新的框架属性ymetadata(typeof(IRCTabItem));
}
公共静态只读RoutedEvent CloseTabEvent=
EventManager.RegisterRoutedEvent(“CloseTab”、RoutingStrategy.Bubble、,
typeof(RoutedEventHandler),typeof(IRCTabItem));
公共事件路由EventHandler关闭选项卡
{
添加{AddHandler(CloseTabEvent,value);}
remove{RemoveHandler(CloseTabEvent,value);}
}
应用程序模板()上的公共重写无效
{
base.OnApplyTemplate();
Button closeButton=base.GetTemplateChild(“PART_Close”)作为按钮;
如果(关闭按钮!=null)
closeButton.Click+=新建系统.Windows.RoutedEventHandler(closeButton\u Click);
}
无效关闭按钮\单击(对象发送器,System.Windows.routedEventTarget e)
{
this.RaiseEvent(新路由EventArgs(CloseTabEvent,this));
}
公共厕所可关闭
{
获取{return(bool)GetValue(CloseableProperty);}
set{SetValue(CloseableProperty,value);}
}
public static readonly dependencProperty CloseableProperty=dependencProperty.Register(“Closeable”、typeof(bool)、typeof(IRCTabItem)、new FrameworkPropertyMetadata(true、FrameworkPropertyMetadata options.bindstwoway默认值));
公共列表用户列表
{
获取{return(List)GetValue(UserListProperty);}
set{SetValue(UserListProperty,value);}
}
public static readonly dependencProperty UserListProperty=dependencProperty.Register(“UserList”、typeof(List)、typeof(IRCTabItem)、new FrameworkPropertyMetadata(new List()、FrameworkPropertyMetadata options.bindstwoway默认));
公共字符串主题
{
获取{return(string)GetValue(TopicProperty);}
set{SetValue(TopicProperty,value);}
}
public static readonly dependencProperty TopicProperty=dependencProperty.Register(“主题”、typeof(字符串)、typeof(IRCTabItem)、新FrameworkPropertyMetadata(“未连接”,FrameworkPropertyMetadataOptions.bindstwoway默认));
公共布尔警报
{
获取{return(bool)GetValue(HasAlertsProperty);}
set{SetValue(HasAlertsProperty,value);}
}
public static readonly dependencProperty HasAlertsProperty=dependencProperty.Register(“HasAlerts”、typeof(bool)、typeof(IRCTabItem)、new FrameworkPropertyMetadata(false、FrameworkPropertyMetadata options.bindstwoway默认));
}
因此,我的问题是:

我的做法是否正确(最佳实践)? 如果是,如何将DataTemplate绑定到属性? 如果不是这样的话,实现我想要实现的目标的正确方法是什么

编辑1:添加Peter Stephens建议 编辑2:添加可见的编辑摘要
编辑3:Tags

您遇到的一个问题是依赖项属性的实现不正确

主题应该这样实现:

public String Topic 
{ 
    get { return (string) GetValue(TopicProperty); }
    set { SetValue(TopicProperty, value); }
}
public static readonly DependencyProperty TopicProperty = 
    DependencyProperty.Register("Topic", typeof(String), 
        typeof(IRCTabItem), new FrameworkPropertyMetadata("Not Connected", 
        FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

您需要将CLR属性视为围绕WPF dependency属性的语法糖。让WPF属性来处理值的存储,否则您将有效地拥有两个具有两个不同值的属性。

我相信您的绑定表达式缺少相对源的模式

试试这个:

<TextBox Text="{Binding Topic, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type t:IRCTabItem}}}" />


模式的默认值为空,因此如果不包括该设置,则可能无法很好地进行设置。

谢谢您的回复。我已经添加了此修改,但没有任何更改:(当你编辑你的问题时,你可能应该添加一些可见的注释,这样一些现有的答案就不再有意义了。另外,当你按照彼得·斯蒂芬斯的建议修改代码时,它修复了什么吗?我以为我已经添加了一个编辑摘要-现在就可以了。彼得·斯蒂芬斯建议的东西不是吗有什么明显的区别吗