如何声明也可以在不绑定的情况下设置的 DependencyProperty
How to declare a DependencyProperty that could also be set without binding
我知道我可以这样声明一个新的依赖关系属性:
public String PropertyPath
{
get { return (String)GetValue(PropertyPathProperty); }
set { SetValue(PropertyPathProperty, value); }
}
public static readonly DependencyProperty PropertyPathProperty =
DependencyProperty.Register(nameof(PropertyPath), typeof(String),
typeof(NotEmptyStringTextBox),
new FrameworkPropertyMetadata(PropertyPath_PropertyChanged));
protected static void PropertyPath_PropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var ctl = d as NotEmptyStringTextBox;
var binding = new Binding(ctl.PropertyPath)
{
ValidationRules = { new NotEmptyStringRule() },
// Optional. With this, the bound property will be updated and validation
// will be applied on every keystroke.
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
ctl.StringBox.SetBinding(TextBox.TextProperty, binding);
}
但是 UserControl 只能接收一个字符串,并绑定到 属性 的名称。
我想要的是能够拥有与“经典”属性相同的行为,您可以绑定到它,也可以给它一个静态值。
我的用法是一个布尔值,它修改 UserControl 的显示状态,静态地使用固定值或动态地绑定,这取决于用例。
也许我最初建立依赖性 属性 的方式不正确,但我可以使用它:
<inputboxes:NotEmptyStringTextBox
Grid.Column="1"
PropertyPath="Name"/>
这将从 DataContext 绑定“名称”属性,但我不能将它与原始字符串一起使用,因为它会产生 BindingExpression 错误:“属性 未找到”
编辑:
我现在尝试了以下方法:
public bool Test
{
get { return (bool)GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}
public static readonly DependencyProperty TestProperty =
DependencyProperty.Register(nameof(Test), typeof(bool),
typeof(DamageTemplateListEditableUserControl));
我声明了这个新的 属性,但我仍然无法绑定任何东西,只接受原始值
您不应在回调中创建新的绑定。事实上,你根本不需要任何回调。
将依赖项 属性 重命名为更好的名称,例如“文本”,并将 StringBox
的 Text
属性 绑定到您的依赖项 [=28] 的当前值=] 像这样:
<TextBox x:Name="StringBox"
Text="{Binding Text, RelativeSource={RelativeSource AncestorType=local:NotEmptyStringTextBox},
UpdateSourceTrigger=PropertyChanged}" />
然后您可以像往常一样设置或绑定依赖项 属性。
如果您真的想要一个“PropertyPath”属性,它不应该是一个您可以绑定某些东西的依赖项 属性,而是一个您可以绑定的简单 CLR 属性设置为 string
,表示要绑定到的 属性 的 名称。
例如,ItemsControl
的 DisplayMemberPath
属性 是如何实现的。
我知道我可以这样声明一个新的依赖关系属性:
public String PropertyPath
{
get { return (String)GetValue(PropertyPathProperty); }
set { SetValue(PropertyPathProperty, value); }
}
public static readonly DependencyProperty PropertyPathProperty =
DependencyProperty.Register(nameof(PropertyPath), typeof(String),
typeof(NotEmptyStringTextBox),
new FrameworkPropertyMetadata(PropertyPath_PropertyChanged));
protected static void PropertyPath_PropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var ctl = d as NotEmptyStringTextBox;
var binding = new Binding(ctl.PropertyPath)
{
ValidationRules = { new NotEmptyStringRule() },
// Optional. With this, the bound property will be updated and validation
// will be applied on every keystroke.
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
ctl.StringBox.SetBinding(TextBox.TextProperty, binding);
}
但是 UserControl 只能接收一个字符串,并绑定到 属性 的名称。
我想要的是能够拥有与“经典”属性相同的行为,您可以绑定到它,也可以给它一个静态值。 我的用法是一个布尔值,它修改 UserControl 的显示状态,静态地使用固定值或动态地绑定,这取决于用例。
也许我最初建立依赖性 属性 的方式不正确,但我可以使用它:
<inputboxes:NotEmptyStringTextBox
Grid.Column="1"
PropertyPath="Name"/>
这将从 DataContext 绑定“名称”属性,但我不能将它与原始字符串一起使用,因为它会产生 BindingExpression 错误:“属性 未找到”
编辑: 我现在尝试了以下方法:
public bool Test
{
get { return (bool)GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}
public static readonly DependencyProperty TestProperty =
DependencyProperty.Register(nameof(Test), typeof(bool),
typeof(DamageTemplateListEditableUserControl));
我声明了这个新的 属性,但我仍然无法绑定任何东西,只接受原始值
您不应在回调中创建新的绑定。事实上,你根本不需要任何回调。
将依赖项 属性 重命名为更好的名称,例如“文本”,并将 StringBox
的 Text
属性 绑定到您的依赖项 [=28] 的当前值=] 像这样:
<TextBox x:Name="StringBox"
Text="{Binding Text, RelativeSource={RelativeSource AncestorType=local:NotEmptyStringTextBox},
UpdateSourceTrigger=PropertyChanged}" />
然后您可以像往常一样设置或绑定依赖项 属性。
如果您真的想要一个“PropertyPath”属性,它不应该是一个您可以绑定某些东西的依赖项 属性,而是一个您可以绑定的简单 CLR 属性设置为 string
,表示要绑定到的 属性 的 名称。
例如,ItemsControl
的 DisplayMemberPath
属性 是如何实现的。