假设我有一个非常简单的UserControl - 对于所有意图和目的 - 只不过是TextBox:
public partial class FooBox : UserControl
{
public static readonly DependencyProperty FooTextProperty =
DependencyProperty.Register("FooText", typeof(string), typeof(FooBox));
public FooBox()
{
InitializeComponent();
}
public string FooText
{
get { return textBlock.Text; }
set { textBlock.Text = value; }
}
}
<UserControl x:Class="Namespace.FooBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid>
<TextBlock x:Name="textBlock" />
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
在表格上,它被声明为:
<local:FooBox FooText="{Binding Name}" />
Run Code Online (Sandbox Code Playgroud)
表单的DataContext设置为具有Name属性的对象.但这不适合我.我错过了什么?
Mat*_*ton 20
在DependencyProperty中的属性声明的"get"和"set"部分实际上并不是由WPF的数据绑定系统调用的 - 它们基本上只是为了满足编译器.
相反,将您的属性声明更改为如下所示:
public string FooText
{
get { return (string)GetValue(FooTextProperty); }
set { SetValue(FooTextProperty, value); }
}
Run Code Online (Sandbox Code Playgroud)
......和你的XAML:
<UserControl ...
x:Name="me">
<Grid>
<TextBlock Text="{Binding FooText,ElementName=me}" />
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
现在你的TextBox.Text直接绑定到"FooText"属性,所以你可以将FooText属性绑定到"Name",就像你现在正在做的那样.
另一种方法是将TextBlock.Text绑定到一个RelativeSource绑定,该绑定在类型为"FooBox"的第一个祖先上找到FooText属性,但我发现这比仅给控件一个内部x:Name和using元素更复杂捆绑.
结果真正的问题是我期待WPF框架设置我的公共属性,然后我的代码将响应更改并根据新值进行渲染.不是这样.WPF所做的是直接调用SetValue()并完全绕过公共属性.我必须做的是使用DependencyPropertyDescriptor.AddValueChanged接收属性更改通知并对其做出响应.它看起来像(在ctor内):
var dpd = DependencyPropertyDescriptor
.FromProperty(MyDependencyProperty, typeof(MyClass));
dpd.AddValueChanged(this, (sender, args) =>
{
// Do my updating.
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
14937 次 |
最近记录: |