访问自定义用户控件的ContentTemplate中的自定义属性
本文关键字:ContentTemplate 自定义属性 控件 自定义 用户 访问 | 更新日期: 2023-09-27 18:16:58
我有以下自定义用户控件:
namespace MyApp.Controls {
public partial class ArticleButton: UserControl {
public ArticleButton () {
InitializeComponent ();
}
public static readonly DependencyProperty TitleProperty;
static ArticleButton () {
TitleProperty = DependencyProperty.RegisterAttached ("Title",
typeof (String), typeof (ArticleButton));
}
[Description ("The name of the article."), Category ("Common Properties")]
public String Title {
get { return "TEST"; }
}
}
}
对应的XAML
:
<UserControl x:Class="MyApp.Controls.ArticleButton"
Name="UC"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MyApp.Controls">
<Button Name="button" Click="button_Click" Style="{StaticResource defaultButtonStyle}">
<Button.ContentTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Path=Title, ElementName=UC}" />
</Grid>
</DataTemplate>
</Button.ContentTemplate>
</Button>
</UserControl>
其中defaultButtonStyle
在App.xaml
中定义(还有更多,但这应该足够了):
<Style TargetType="Button" x:Key="defaultButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="1"
Padding="4,2"
BorderBrush="DarkGray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我的问题是没有显示属性Title
,我尝试了以下也不工作:
<TextBlock Text="{Binding Path=Title, ElementName=UC}" />
<TextBlock Text="{Binding Path=Title, RelativeSource={RelativeSource TemplatedParent}}" />
<TextBlock Text="{Binding Path=Title, RelativeSource={RelativeSource AncestorType={x:Type local:ArticleButton}}}" />
我发现很多帖子有类似的问题,但没有一个帮助…我认为问题是,我试图访问内部按钮的内容模板内的自定义用户控件的自定义属性,但如何做到这一点。
总结评论你的第3个RelativeSource
绑定
<TextBlock Text="RelativeSource={RelativeSource AncestorType={x:Type local:ArticleButton}}"/>
应该工作良好,只是使用Register
而不是RegisterAttached
。至于其他绑定,{Binding Path=Title, ElementName=UC}
不起作用,因为ConrtrolTemplate
有自己的名称作用域,{Binding Path=Title, RelativeSource={RelativeSource TemplatedParent}}"
不起作用,因为您没有针对Button
设置属性,而是针对UserControl
。
另一个问题是,您针对CLR包装器设置了默认值,并且,正如本MSDN页面所述,CLR包装器被忽略,GetValue
/SetValue
方法被直接调用TitleProperty
WPF XAML处理器在加载二进制XAML和处理作为依赖属性的属性时使用属性系统方法来处理依赖属性。这有效地绕过了属性包装器。当你实现自定义依赖属性时,你必须考虑到这种行为,并且应该避免在属性包装器中放置除属性系统方法GetValue和SetValue之外的任何其他代码。
如果你想指定默认值和/或属性改变回调,那么当你创建DependencyProperty
时,Register
方法的另一个变体也接受PropertyMetadata
参数,你可以设置这些值。
使用依赖属性时需要注意的另一件事是,因为它的定义是静态的,默认值将在ArticleButton
的所有实例之间共享。所以如果你的类型是list或者其他类你在PropertyMetadata
中将其初始化为不同的值那么null相同的实例将作为默认值
public partial class ArticleButton : UserControl
{
public ArticleButton()
{
InitializeComponent();
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register(
"Title",
typeof(String),
typeof(ArticleButton),
new PropertyMetadata("Test", TitlePropertyChanged));
private static void TitlePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as ArticleButton).TitlePropertyChanged(e);
}
private void TitlePropertyChanged(DependencyPropertyChangedEventArgs e)
{
//do something when property changed value
}
public String Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
}