C# 通过我自己的代码检测对DependencyProperty的更改
我的控件有一个映射到私有变量的属性。设置属性时,我还需要存储某个其他变量。当属性的私有变量由我自己的控制代码设置时,不能进行这种特殊处理。一切都好 我现在需要将其重构为DependencyProperty。我这里只有一个更改处理程序,对该属性的所有(也是内部)访问都必须通过DependencyProperty框架。没有更多的私有变量可以直接设置。现在,我自己的代码所做的每一项更改看起来都与来自外部源(如控件或数据绑定的用户)的更改完全相同 在我的属性更改处理程序中,如何确定值更改是来自我的代码还是其他地方 这是旧代码:C# 通过我自己的代码检测对DependencyProperty的更改,c#,.net,wpf,dependency-properties,C#,.net,Wpf,Dependency Properties,我的控件有一个映射到私有变量的属性。设置属性时,我还需要存储某个其他变量。当属性的私有变量由我自己的控制代码设置时,不能进行这种特殊处理。一切都好 我现在需要将其重构为DependencyProperty。我这里只有一个更改处理程序,对该属性的所有(也是内部)访问都必须通过DependencyProperty框架。没有更多的私有变量可以直接设置。现在,我自己的代码所做的每一项更改看起来都与来自外部源(如控件或数据绑定的用户)的更改完全相同 在我的属性更改处理程序中,如何确定值更改是来自我的代码还
private DateTime selectedTime;
private int intendedDay;
public DateTime SelectedTime
{
get { return selectedTime; }
set
{
selectedTime = value;
intendedDay = selectedTime.Day;
}
}
在此代码中,我可以直接设置selectedTime
,而不影响intendedDay
,只有当selectedTime
从外部分配了一个新值,或者当我认为我的控件合适时,才能设置该值
DependencyProperty仅允许我检测任何更改:
public static DependencyProperty SelectedTimeProperty = DependencyProperty.Register(
"SelectedTime",
typeof(DateTime),
typeof(DateTimeTextBox),
new PropertyMetadata(SelectedTimeChanged));
public DateTime SelectedTime
{
get { return (DateTime) GetValue(SelectedTimeProperty); }
set { SetValue(SelectedTimeProperty, value); }
}
private static void SelectedTimeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
DateTimeTextBox control = (DateTimeTextBox) obj;
// This must not happen where I previously assigned the private variable:
control.intendedDay = control.SelectedTime.Day;
}
private int intendedDay;
因此,当我以前分配私有变量时,我现在只能设置dependency属性,它也将更改
intendedDay
为什么不将dependency属性包装为普通属性?设置属性仍然会设置dependency属性,而设置private属性不会设置intendedDay值
private DateTime selectedTime
{
get { return (DateTime) GetValue(SelectedTimeProperty); }
set { SetValue(SelectedTimeProperty, value); }
}
public DataTime SelectedTime
{
get { return selectedTime; }
set
{
selectedTime = value;
intendedDay = selectedTime.Day;
}
}
正如克莱门斯在评论中解释的那样,我添加了一个私有变量,用于指示我当前是否正在从自己的代码更新该属性。每当我想要抑制外部值更改处理时,我都将其设置为true,然后设置为false。因此,我可以区分是内部值更改还是外部值更改。问题在于,使用依赖项属性时,您无法访问实际的数据存储。(CLR属性只是代码的快捷方式。其他方法不需要使用它。)并且可以通过绑定直接更改实际的数据存储,中间没有层。这也必须始终设置
intendedDay
。现在,我自己的控制代码如何才能在不更改预定日期的情况下更改属性值?啊,我明白了。因此,如果SetValue必须始终设置intendedDay(如果被除此之外的任何调用),那么我们有一个有趣的问题。让我仔细考虑一下你的评论,看起来你已经想出了一个有效的解决方案。我不知道有任何CLR magig允许您在不使用反射和stackframe=slow and ught的情况下确定SetValue方法的调用方。我记得当Windows关闭或应用程序退出时,会出现类似关闭原因的情况。依赖项属性可能也有类似的“更新原因”。StackFrame没有选择,它太容易失败,而且成本太高。当需要时,我可以在控件中设置这两个变量。问题是我只需要改变一个。但是当另一个也被自动更新时,它们都粘在一起了。我可以建议使用一个丑陋的解决方案,带有私有标志和特殊的SetSelectedTime方法,它使用此标志来控制SelectedTimeChanged
。但这是一个棘手的问题,可能会导致一些并发问题。我提出了一个InternalSetValue方法,该方法设置标志,然后调用SetValue,然后清除标志。啊,你是说私有bool正在更新
,它是围绕设置依赖项属性设置的true
,并在更改处理程序中进行计算的?