尝试设置自定义 DependencyObject。明显漏掉了什么
Trying to setup a custom DependencyObject. Clearly missing something
我在 UWP 应用程序中有以下内容。请注意,我的元素来自 DependencyObject,而不是来自控件、面板等。但是当我调用测试方法 MessWithBindings() 时,绑定不起作用。 PropertyChanged 方法会触发,但 PropertyChangedEventHandler 为 null,因此它不执行任何操作。我应该以某种方式直接设置事件处理程序吗?还是我错过了另一个创建它的电话?
顺便说一下,我有 BindWidth/BindHeight 方法的 FrameworkElement 版本,它们工作得很好。
class WindowsElement: DependencyObject, INotifyPropertyChanged
{
public WindowsElement()
{
}
private double _Width { get; set; }
private double _Height { get; set; }
public double Width
{
get
{
return _Width;
}
set
{
if (_Width != value)
{
_Width = value;
OnPropertyChanged("Width");
}
}
}
public double Height
{
get
{
return _Height;
}
set
{
if (_Height != value)
{
_Height = value;
OnPropertyChanged("Height");
}
}
}
public static readonly DependencyProperty WidthProperty = DependencyProperty.Register(
"Width",
typeof(double),
typeof(WindowsElement),
null);
public static readonly DependencyProperty HeightProperty = DependencyProperty.Register(
"Height",
typeof(double),
typeof(WindowsElement),
null);
private double _ActualWidth { get; set; }
public double ActualWidth {
get
{
return _ActualWidth;
}
set
{
if (_ActualWidth != value)
{
_ActualWidth = value;
OnPropertyChanged("ActualWidth");
}
}
}
private double _ActualHeight { get; set; }
public double ActualHeight {
get
{
return _ActualHeight;
}
set
{
if (_ActualHeight != value)
{
_ActualHeight = value;
OnPropertyChanged("ActualHeight");
}
}
}
public static readonly DependencyProperty ActualWidthProperty = DependencyProperty.Register(
"ActualWidth",
typeof(double),
typeof(WindowsElement),
null);
public static readonly DependencyProperty ActualHeightProperty = DependencyProperty.Register(
"ActualHeight",
typeof(double),
typeof(WindowsElement),
null);
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
internal void SetBinding(DependencyProperty property, Binding b)
{
BindingOperations.SetBinding(this, property, b);
}
public static void MessWithBindings()
{
WindowsElement we1 = new WindowsElement();
WindowsElement we2 = new WindowsElement();
we1.BindWidth(we2);
we1.BindHeight(we2);
we2.Width = 12;
we2.ActualWidth = 13;
we2.ActualHeight = 666;
CommonDebug.LogLine(we1, we1.Width, we1.Height, we1.ActualWidth, we1.ActualHeight, we2, we2.ActualWidth, we2.ActualHeight);
CommonDebug.DoNothing();
}
}
internal static class WindowsElementAdditions
{
public static void BindWidth(this WindowsElement bindMe, WindowsElement toMe)
{
Binding b = new Binding();
b.Mode = BindingMode.OneWay;
b.Source = toMe.ActualWidth;
bindMe.SetBinding(WindowsElement.WidthProperty, b);
}
public static void BindHeight(this WindowsElement bindMe, WindowsElement toMe)
{
Binding b = new Binding();
b.Mode = BindingMode.OneWay;
b.Source = toMe.ActualHeight;
bindMe.SetBinding(WindowsElement.HeightProperty, b);
}
}
依赖项 属性 的 属性 包装器必须调用 DependencyObject 的 GetValue
和 SetValue
方法,例如
class WindowsElement : DependencyObject
{
public static readonly DependencyProperty WidthProperty =
DependencyProperty.Register(
"Width", typeof(double), typeof(WindowsElement), null);
public double Width
{
get { return (double)GetValue(WidthProperty); }
set { SetValue(WidthProperty, value); }
}
}
而且它不能调用任何其他东西。当 属性 由 Binding(或 Style Setter 和其他一些来源)设置时,框架不会调用 属性 包装器,而是直接调用 SetValue
。
为了在内部获得有关更改的 属性 值的通知,class 应该通过 PropertyMetadata
注册一个 PropertyChangedCallback
public static readonly DependencyProperty WidthProperty =
DependencyProperty.Register(
"Width", typeof(double), typeof(WindowsElement),
new PropertyMetadata((double)0, WidthPropertyChanged));
private static void WidthPropertyChanged(
DependencyObject o, DependencyPropertyChangedEventArgs e)
{
WindowsElement element = (WindowsElement)o;
double width = (double)e.NewValue;
// update element here if necessary
}
依赖属性已经实现了一种机制,可以通知侦听器(例如绑定)有关更改的 属性 值,因此无需在此处实现 INotifyPropertyChanged
。
我在 UWP 应用程序中有以下内容。请注意,我的元素来自 DependencyObject,而不是来自控件、面板等。但是当我调用测试方法 MessWithBindings() 时,绑定不起作用。 PropertyChanged 方法会触发,但 PropertyChangedEventHandler 为 null,因此它不执行任何操作。我应该以某种方式直接设置事件处理程序吗?还是我错过了另一个创建它的电话?
顺便说一下,我有 BindWidth/BindHeight 方法的 FrameworkElement 版本,它们工作得很好。
class WindowsElement: DependencyObject, INotifyPropertyChanged
{
public WindowsElement()
{
}
private double _Width { get; set; }
private double _Height { get; set; }
public double Width
{
get
{
return _Width;
}
set
{
if (_Width != value)
{
_Width = value;
OnPropertyChanged("Width");
}
}
}
public double Height
{
get
{
return _Height;
}
set
{
if (_Height != value)
{
_Height = value;
OnPropertyChanged("Height");
}
}
}
public static readonly DependencyProperty WidthProperty = DependencyProperty.Register(
"Width",
typeof(double),
typeof(WindowsElement),
null);
public static readonly DependencyProperty HeightProperty = DependencyProperty.Register(
"Height",
typeof(double),
typeof(WindowsElement),
null);
private double _ActualWidth { get; set; }
public double ActualWidth {
get
{
return _ActualWidth;
}
set
{
if (_ActualWidth != value)
{
_ActualWidth = value;
OnPropertyChanged("ActualWidth");
}
}
}
private double _ActualHeight { get; set; }
public double ActualHeight {
get
{
return _ActualHeight;
}
set
{
if (_ActualHeight != value)
{
_ActualHeight = value;
OnPropertyChanged("ActualHeight");
}
}
}
public static readonly DependencyProperty ActualWidthProperty = DependencyProperty.Register(
"ActualWidth",
typeof(double),
typeof(WindowsElement),
null);
public static readonly DependencyProperty ActualHeightProperty = DependencyProperty.Register(
"ActualHeight",
typeof(double),
typeof(WindowsElement),
null);
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
internal void SetBinding(DependencyProperty property, Binding b)
{
BindingOperations.SetBinding(this, property, b);
}
public static void MessWithBindings()
{
WindowsElement we1 = new WindowsElement();
WindowsElement we2 = new WindowsElement();
we1.BindWidth(we2);
we1.BindHeight(we2);
we2.Width = 12;
we2.ActualWidth = 13;
we2.ActualHeight = 666;
CommonDebug.LogLine(we1, we1.Width, we1.Height, we1.ActualWidth, we1.ActualHeight, we2, we2.ActualWidth, we2.ActualHeight);
CommonDebug.DoNothing();
}
}
internal static class WindowsElementAdditions
{
public static void BindWidth(this WindowsElement bindMe, WindowsElement toMe)
{
Binding b = new Binding();
b.Mode = BindingMode.OneWay;
b.Source = toMe.ActualWidth;
bindMe.SetBinding(WindowsElement.WidthProperty, b);
}
public static void BindHeight(this WindowsElement bindMe, WindowsElement toMe)
{
Binding b = new Binding();
b.Mode = BindingMode.OneWay;
b.Source = toMe.ActualHeight;
bindMe.SetBinding(WindowsElement.HeightProperty, b);
}
}
依赖项 属性 的 属性 包装器必须调用 DependencyObject 的 GetValue
和 SetValue
方法,例如
class WindowsElement : DependencyObject
{
public static readonly DependencyProperty WidthProperty =
DependencyProperty.Register(
"Width", typeof(double), typeof(WindowsElement), null);
public double Width
{
get { return (double)GetValue(WidthProperty); }
set { SetValue(WidthProperty, value); }
}
}
而且它不能调用任何其他东西。当 属性 由 Binding(或 Style Setter 和其他一些来源)设置时,框架不会调用 属性 包装器,而是直接调用 SetValue
。
为了在内部获得有关更改的 属性 值的通知,class 应该通过 PropertyMetadata
注册一个PropertyChangedCallback
public static readonly DependencyProperty WidthProperty =
DependencyProperty.Register(
"Width", typeof(double), typeof(WindowsElement),
new PropertyMetadata((double)0, WidthPropertyChanged));
private static void WidthPropertyChanged(
DependencyObject o, DependencyPropertyChangedEventArgs e)
{
WindowsElement element = (WindowsElement)o;
double width = (double)e.NewValue;
// update element here if necessary
}
依赖属性已经实现了一种机制,可以通知侦听器(例如绑定)有关更改的 属性 值,因此无需在此处实现 INotifyPropertyChanged
。