[英]WPF MVVM Dependancy property binding not working
I'm using a beavior in a TextBox control to filter input via a regex.我在 TextBox 控件中使用行为来通过正则表达式过滤输入。 For this I added a dependency property to get the regex value.
为此,我添加了一个依赖属性来获取正则表达式值。 When I set directly in xaml the value, It works properly but when I'm trying to pass it with a bind property, the regex value is not setted in the dependency property:
当我直接在 xaml 中设置该值时,它可以正常工作,但是当我尝试使用绑定属性传递它时,未在依赖属性中设置正则表达式值:
public class TextBoxInputRegExBehaviour : Behavior<TextBox>
{
public static readonly DependencyProperty RegularExpressionProperty =
DependencyProperty.Register("RegularExpression", typeof(string), typeof(TextBoxInputRegExBehaviour), new FrameworkPropertyMetadata(".*"));
public string RegularExpression
{
get { return (string)GetValue(RegularExpressionProperty);
set { SetValue(RegularExpressionProperty, value); }
}
...
}
When using this format, no problem:使用这种格式时,没问题:
<TextBox Text="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Style="{StaticResource ValidableTextBox}">
<i:Interaction.Behaviors>
<behaviours:TextBoxInputRegExBehaviour RegularExpression="[0-9.]+$" />
</i:Interaction.Behaviors>
</TextBox>
But not working with binding:但不适用于绑定:
<TextBox Text="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Style="{StaticResource ValidableTextBox}">
<i:Interaction.Behaviors>
<behaviours:TextBoxInputRegExBehaviour RegularExpression="{Binding MyRegExString}" />
</i:Interaction.Behaviors>
</TextBox>
What did I wrong?我做错了什么?
Try to register RegularExpressionProperty
to bind two-way by default:尝试注册
RegularExpressionProperty
,默认绑定双向:
public static readonly DependencyProperty RegularExpressionProperty =
DependencyProperty.Register("RegularExpression",
typeof(string),
typeof(TextBoxInputRegExBehaviour),
new FrameworkPropertyMetadata(".*", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
Since Behavior<T>
does not extend FrameworkElement
, it does not have a DataContext
.由于
Behavior<T>
没有扩展FrameworkElement
,因此它没有DataContext
。 You can either use Binding.RelativeSource
to traverse the visual tree to find the next parent FrameworkElement
(and its DataContext
property).您可以使用
Binding.RelativeSource
遍历可视化树以查找下一个父FrameworkElement
(及其DataContext
属性)。
Or implement an attached bahavior (based on attached properties).或者实现附加的行为(基于附加的属性)。
Since attached properties are usually attached to a FrameworkElement
, you can always bind to the attaching element's DataContext
(which is what you would naturally do).由于附加属性通常附加到
FrameworkElement
,因此您始终可以绑定到附加元素的DataContext
(这是您自然会做的)。
You can enforce a type constraint by checking the attaching element's type in the callback and throw an exception if necessary.您可以通过在回调中检查附加元素的类型来强制执行类型约束,并在必要时抛出异常。
Attached behavior usage example附加行为使用示例
<TextBox TextBoxInputRegExBehaviour.IsEnabled="True"
TextBoxInputRegExBehaviour.RegularExpression="{Binding MyRegExString}"
Text="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
Style="{StaticResource ValidableTextBox}" />
TextBoxInputRegExBehaviour.cs TextBoxInputRegExBehaviour.cs
Implementation of an attached behavior附加行为的实现
public class TextBoxInputRegExBehaviour : DependencyObject
{
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached(
"IsEnabled",
typeof(bool),
typeof(TextBoxInputRegExBehaviour),
new FrameworkPropertyMetadata(default(bool), OnIsEnabledChanged));
public static void SetIsEnabled(DependencyObject attachingElement, bool value)
=> attachingElement.SetValue(IsEnabledProperty, value);
public static bool GetIsEnabled(DependencyObject attachingElement)
=> (bool)attachingElement.GetValue(IsEnabledProperty);
public static readonly DependencyProperty RegularExpressionProperty =
DependencyProperty.RegisterAttached(
"RegularExpression",
typeof(string),
typeof(TextBoxInputRegExBehaviour),
new FrameworkPropertyMetadata(".*", OnRegularExpressionChanged));
public static void SetRegularExpression(DependencyObject attachingElement, string value)
=> attachingElement.SetValue(RegularExpressionProperty, value);
public static string GetRegularExpression(DependencyObject attachingElement)
=> (string)attachingElement.GetValue(RegularExpressionProperty);
private static void OnIsEnabledChanged(DependencyObject attachingElement, DependencyPropertyChangedEventArgs e)
{
// Prior to C# 9: if (!(attachingElement is TextBox textBox))
if (attachingElement is not TextBox textBox)
{
// Optionally throw an exception if this makes sense
return;
}
if ((bool)e.NewValue)
{
// TODO::Handle behavior enabled,
// for example subscribe to events of the TextBox instance
}
else
{
// TODO::Handle behavior disabled,
// for example unsubscribe from events of the TextBox instance
}
}
private static void OnRegularExpressionChanged(DependencyObject attachingElement, DependencyPropertyChangedEventArgs e)
{
// Prior to C# 9: if (!(attachingElement is TextBox textBox))
if (attachingElement is not TextBox textBox)
{
// Optionally throw an exception if this makes sense
return;
}
// TODO::Handle the changed RegularExpression value
}
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.