WPF选项卡项自定义内容模板
我已经尝试了一段时间了,在WindowForms中做起来很简单 我正在制作一个IRC客户端,将有许多选项卡,每个通道连接一个选项卡。 每个选项卡都需要显示一些内容,如用户列表、消息历史记录和主题 在WindowForms中,我只是继承了TabItem,添加了一些自定义属性和控件,然后就完成了 在WPF中,我在解决如何做到这一点上遇到了一些小问题 我已经尝试了很多方法,下面是我当前的方法,但是我无法让TextBox绑定到Topic属性WPF选项卡项自定义内容模板,wpf,datatemplate,tabcontrol,tabitem,Wpf,Datatemplate,Tabcontrol,Tabitem,我已经尝试了一段时间了,在WindowForms中做起来很简单 我正在制作一个IRC客户端,将有许多选项卡,每个通道连接一个选项卡。 每个选项卡都需要显示一些内容,如用户列表、消息历史记录和主题 在WindowForms中,我只是继承了TabItem,添加了一些自定义属性和控件,然后就完成了 在WPF中,我在解决如何做到这一点上遇到了一些小问题 我已经尝试了很多方法,下面是我当前的方法,但是我无法让TextBox绑定到Topic属性 <Style TargetType="{x:Ty
<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}}}" />
模式的默认值为空,因此如果不包括该设置,则可能无法很好地进行设置。谢谢您的回复。我已经添加了此修改,但没有任何更改:(当你编辑你的问题时,你可能应该添加一些可见的注释,这样一些现有的答案就不再有意义了。另外,当你按照彼得·斯蒂芬斯的建议修改代码时,它修复了什么吗?我以为我已经添加了一个编辑摘要-现在就可以了。彼得·斯蒂芬斯建议的东西不是吗有什么明显的区别吗