WPF XAML,我有一个自定义控件我写了包装查找。 在典型的政府方式中,他们有一个查找表,可以查找所有可能的查找。 我的自定义控件将抛出一个弹出式叠加层,要求他们从列表中的项目中进行选择。 我的问题特别涉及从我的调用表单到我的控件属性到我的底层控制VM的数据绑定。
我正在调用这样的控件:
<Controls:LookupSelector SelectedLookupValueId="{Binding Path=DataContext.SelectedHarvestMethod, ElementName=SurveyFormWindow, Mode=TwoWay}" />
(其他垃圾邮件被删除) 在这种情况下,需要显式DataContext,因为控件的实际datacontext是其自己的视图模型。 SelectedHarvestMethod是ViewModel表单上的属性。
它在“新窗体”模式下工作,控件负责设置自己的值(控件包含一个按钮,当您单击它时,会弹出一个按钮,并选择所需的查找数据值)。 这就像我说的那样工作正常,甚至可以回到上面代码中的'SelectedHarvestMethod'。我可以使用这个并且确信我的ViewModel总是将选定的id分配给该属性。
但现在我正在进行“编辑现有表单”模式,我从数据库加载数据并在视图模型中设置属性。所以我设置'SelectedHarvestMethod'并且代码工作正常(在setter中命中断点)但是'SelectedLookupValueId'上的结果setter没有被调用 - 值永远不会通过。
'SelectedLookupValueId'是控件视图模型上的DP:
public static readonly DependencyProperty SelectedLookupValueIdProperty =
DependencyProperty.Register("SelectedLookupValueId", typeof(int), typeof(LookupSelector), new UIPropertyMetadata(0));
public int SelectedLookupValueId
{
get { return (int) GetValue(SelectedLookupValueIdProperty); }
set { SetValue(SelectedLookupValueIdProperty, value); ViewModel.SetPreSelectedLookupValueId(value); }
}
输出窗口或事件日志中没有错误或写在我的鞋子底部。 插入的调试转换器显示绝对分配了整数值。 正如评论中所提到的,VM当然会实现INotifyPropertyChanged,并且正在提升事件。
此外,实际类型是“用户控制”,而不是自定义控件:它涉及XAML。
为什么不调用我的控件的属性设置器?
答案 0 :(得分:15)
为什么不调用我的控件的属性设置器?
我承认我没有读过你的整个问题 - 它太长了;)但是,你确定绑定失败了吗?知道WPF优化了依赖项属性访问,因此不会调用CLR包装器的getter和setter。相反,它会直接调用DependencyObject.GetValue
和DependencyObject.SetValue
,并传入相应的DependencyProperty
实例。
因此,您无法在CLR属性上设置断点以确定是否正在更改d-prop。而是在d-prop的元数据中指定更改处理程序。然后在此处理程序中设置断点。你也可以使用像Snoop这样的工具来看这个。
顺便说一下,这就是为什么你的CLR包装器属性永远不应该只调用GetValue
和SetValue
。它只是为了方便而存在,并且不保证您使用该属性打包的任何额外逻辑都会执行。