dev*_*tal 2 wpf xaml dependency-properties mvvm
我的ViewModel上有一个依赖属性,它是我的View的DataContext.ViewModel没有对View的引用.ViewModel上的属性将引用视图上的控件,但我需要能够在XAML中设置此属性.
这怎么可能?我有一个想法是开发一个具有Property属性和Value属性的自定义控件,因此您可以在View中执行类似的操作以在ViewModel上设置属性:
<PropertySetter Property="{Binding MyViewModelDependencyProperty}" Value="{Binding ElementName=aControlOnMyView" />
Run Code Online (Sandbox Code Playgroud)
在我走这条路之前,我想检查一下我是否还有其他方法可以采取?
感谢雷的详细回复,但如果我给你一些关于我试图解决的问题的更多细节,你可能会更好地了解我为什么提到我做的方法.
基本上,我正在尝试做的是当用户点击按钮时将焦点设置为文本框.我写了一个附加属性,你可以将它附加到Button控件,指定触发事件是什么(在这种情况下是'Click'事件),然后是要关注的控件.这非常好用,并且保留了XAML中的所有内容.
但是,我现在有一个用例,其焦点应设置为按钮上的单击事件的任意文本框,该按钮是工具栏的一部分.这个工具栏本身就是一个用户控件,它位于另一个用户控件内,该控件位于另一个用户控件内!此工具栏需要可以在各种不同的表单中重复使用,并且每次单击按钮后设置焦点的控件在每个表单中都会有所不同.
这就是为什么我想让焦点控件(即文本框)成为视图模型本身的属性(在我的ViewModel基础上是精确的),并且具有ViewModel基本代码(工具栏绑定到的),设置单击按钮时对焦于控件(并且在ViewModel基础上调用例如Add/Edit方法).
在单元测试中,关注属性的控件将为null,因此它的.Focus()方法就不会被调用.所以我在那里看不到问题.我的问题是如何从XAML设置焦点控制属性,这就是我有PropertySetter想法的原因.
我不喜欢ViewModel对视图上的控件有任何引用这一事实,但我看不到另一种方法来实现我需要的东西.如果决定是否将焦点设置到控件的逻辑非常复杂怎么办?这肯定会在ViewModel中吗?因此,具有此UIElement属性的ViewModel是否有任何损害?它仍然对它所绑定的特定视图一无所知,它只知道在ViewModel上发生某些动作时需要设置焦点.
我的第一反应(也是一个强烈的反应)是这样说的"不要那样做!" 通过为您的视图模型提供对UI的一部分的引用,您打破了使视图模型如此强大和有用的封装.
例如,如果要对视图模型进行单元测试或将其序列化为磁盘,该怎么办?在每种情况下,您的UI都不会出现,因为根本没有视图.您的测试将错过覆盖范围,您的重建将不完整.
如果您的视图模型实际上需要对UI对象的引用,并且没有更好的方法来构建它,那么最好的解决方案是让视图模型本身构造它需要引用的控件.然后,您的视图可以通过绑定将该控件合并为ContentPresenter的内容,并提供用于配置控件的Style,包括用于提供其内容的ControlTemplate.正是如此:
public class MyViewModel
{
public ListBox SpecialControl { get; set; }
public MyViewModel()
{
SpecialControl = new ListBox();
}
}
Run Code Online (Sandbox Code Playgroud)
和
<DataTemplate TargetType="{x:Type local:MyViewModel}">
<DataTemplate.Resources>
<Style TargetType="ListBox" ... />
</DataTemplate.Resources>
...
<ContentPresenter Content="{Binding SpecialControl}" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
其他可能性是:
我的选项#2看起来像这样:
<DataTemplate TargetType="{x:Type MyViewModel}">
...
<TextBox local:PropertyHelper.SetViewModelToThis="SpecialControl" />
...
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
SetViewModelToThis PropertyChangedCallback中的代码将从DataContext获取视图模型,反映它以查找"SpecialControl"属性,然后将其设置为TextBox.请注意,SetViewModelToThis的实现必须考虑到DataContext没有立即设置的可能性,并且可能需要更改它,需要删除旧设置并创建一个新设置.
| 归档时间: |
|
| 查看次数: |
5514 次 |
| 最近记录: |