【发布时间】:2017-10-05 08:59:02
【问题描述】:
我有一个带有 PropertyChangedCallback 依赖属性的自定义控件。属性的值可以从自定义控件的逻辑内部或外部更改(通过用户交互或通过从客户端应用程序设置的值)。
有没有办法知道是什么导致了属性的变化?
我尝试查看“发件人”,但在每种情况下,发件人都是自定义控件本身。
举例说明:
public static readonly DependencyProperty SelectedTimeProperty =
DependencyProperty.Register("SelectedTime", typeof(DateTime?), typeof(TimePickerControl), new PropertyMetadata(null, new PropertyChangedCallback(HandleSelectedTimeChanged)));
public static readonly DependencyProperty HoursProperty =
DependencyProperty.Register("Hours", typeof(object), typeof(TimePickerControl), new PropertyMetadata(@"", (o, e) => ((TimePickerControl)o).OnHoursChanged(o, e.OldValue)));
public static readonly DependencyProperty MinutesProperty =
DependencyProperty.Register("Minutes", typeof(object), typeof(TimePickerControl), new PropertyMetadata(@"", (o, e) => ((TimePickerControl)o).OnMinutesChanged(o, e.OldValue)));
public static readonly DependencyProperty SecondsProperty =
DependencyProperty.Register("Seconds", typeof(object), typeof(TimePickerControl), new PropertyMetadata(@"", (o, e) => ((TimePickerControl)o).OnSecondsChanged(o, e.OldValue)));
因此客户端应用程序可以更新SelectedTime,在这种情况下,Hours、Minutes 和Seconds 将由控件更新。此逻辑在HandleSelectedTimeChanged 中处理。
但是,用户也可以修改Hours、Minutes和Seconds之一,其中SelectedTime必须相应更新。
正如您可能猜到的那样,这会产生一些循环,因为更改 Hours 会导致触发 SelectedTime 回调,这当然会更改 Hours/Mins/Secs再次调用他们的回调被触发。
我只想在更改来自控件外部时调用回调,或者在回调中检测到这一点并立即退出。
到目前为止,我想出的唯一想法是在更改其中一个属性之前立即设置一个私有变量,如果已设置,则在其回调退出中,然后在更改后立即清除它,但这似乎很混乱我。有更好的方法吗?
【问题讨论】:
-
依赖属性在控件内部。如果您也在控制范围内更改它们的值,那么只需使用一些标志:在更改之前设置它,在回调中检查它。另一件事是coerce。
-
“你可能猜到了,这会造成一个循环” 这不应该发生。仅当属性的值实际更改 时才会调用属性更改回调。因此,如果您更改
Hours属性,它的回调可能会设置SelectedTime属性,这反过来又会再次设置Hours属性值。但是,Hours属性值没有改变,所以它的属性改变回调不会被调用。我怀疑您的问题与您的Hours、Minutes和Seconds依赖属性被声明为类型object 有更多关系。它们应该是 int 吗? -
@StevenRands - 这不是一个无限循环,我明白你在说什么,但它创造了一个令人费解的意大利面条流,这使得阅读/调试/维护变得困难,并可能导致其他问题控制范围内。
-
为什么你的
Hours、Minutes和Seconds依赖属性声明为object类型?我本来希望它们是 ints 或其他一些原始值类型。 -
就我所知,您必须忍受不断更新的更新。 DP 并不擅长动态计算。
标签: c# wpf mvvm dependency-properties