我创建了 TextBox 类的派生类 MyTextBox,并添加了一个名为 AString 的依赖属性和一个名为 ContextChangedEvent 的路由事件。在XAML代码中,Text属性绑定到AString属性,但是当我更改Text属性的值时,AString属性的setter没有被触发,这意味着绑定没有生效。这是为什么?
public class MyTextBox : TextBox
{
public static readonly RoutedEvent ContentChangedEvent;
public event RoutedEventHandler ContentChanged
{
add { AddHandler(ContentChangedEvent, value); }
remove { RemoveHandler(ContentChangedEvent, value); }
}
public string AString
{
get { return (string)GetValue(AStringProperty); }
set
{
SetValue(AStringProperty, value);
OnContentChanged();
}
}
public static readonly DependencyProperty AStringProperty;
static MyTextBox()
{
ContentChangedEvent = EventManager.RegisterRoutedEvent("ContentChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyTextBox));
var a = new FrameworkPropertyMetadata("555");
a.BindsTwoWayByDefault = true;
AStringProperty = DependencyProperty.Register("AString", typeof(string), typeof(MyTextBox), a);
}
private void OnContentChanged()
{
RaiseEvent(new RoutedEventArgs(ContentChangedEvent, this));
}
<local:MyTextBox x:Name="mtb1"
ContentChanged="MyTextBox_ContentChanged"
Text="{Binding AString,
RelativeSource={RelativeSource Mode=Self},
Mode=TwoWay}" />
我尝试将绑定模式更改为双向绑定,但没有成功
CLR 属性只是依赖属性的代理包装器。除了获取和设置属性值之外,该包装器中不应该有任何逻辑。
这是正确的实现:
public class MyTextBox : TextBox
{
public event RoutedEventHandler ContentChanged
{
add { AddHandler(ContentChangedEvent, value); }
remove { RemoveHandler(ContentChangedEvent, value); }
}
public static readonly RoutedEvent ContentChangedEvent
= EventManager.RegisterRoutedEvent(
nameof(ContentChanged),
RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(MyTextBox));
public string AString
{
get => (string)GetValue(AStringProperty);
set => SetValue(AStringProperty, value);// OnContentChanged();
}
public static readonly DependencyProperty AStringProperty
= DependencyProperty.Register(
nameof(AString),
typeof(string),
typeof(MyTextBox),
new FrameworkPropertyMetadata("555")
{
BindsTwoWayByDefault = true,
PropertyChangedCallback = OnContentChanged
});
private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((UIElement)d).RaiseEvent(new RoutedEventArgs(ContentChangedEvent, d));
}
}