使用MVVM的WPF ReadOnly依赖项属性

时间:2009-11-17 14:26:39

标签: wpf mvvm binding dependency-properties

我最近覆盖了DevXpress WPF网格,给自己一个SelectedObject属性,我可以从松散绑定的ViewModel访问它。

我已经创建了一个SelectedObject依赖项属性,并在我的XAML中绑定了OneWayToSource。

Everthing工作正常,但如果我尝试将其设为ReadOnly(为了完整性),我会收到编译错误并说我无法绑定到ReadOnly属性。下面的代码编译,我已经包括(但重新列出)我尝试获取属性ReadOnly时尝试的位。

有人可以帮忙吗?

我覆盖的控件的依赖属性如下所示:

  //public static readonly DependencyPropertyKey SelectedRowKey = DependencyProperty.RegisterReadOnly("SelectedObject", typeof(object), typeof(MyGrid), new PropertyMetadata(null));
//public static readonly DependencyProperty SelectedObjectProperty = SelectedRowKey.DependencyProperty;

public readonly static DependencyProperty SelectedObjectProperty = DependencyProperty.Register("SelectedObject", typeof(object), typeof(MyGrid), new PropertyMetadata(null));

public object SelectedObject
{
    get
    {

        return GetValue(SelectedObjectProperty);
    }
    set
    {
        throw new NotImplementedException();
    }
}

XAML是:

 <StackPanel>
  <devxgrid:MyGrid AutoPopulateColumns="True" DataSource="{Binding Animals}" SelectedObject="{Binding MyObject, Mode=OneWayToSource}" Width="300" Height="300">
    <devxgrid:MyGrid.View>
        <MyGrid:TableView AllowEditing="False" Name="GridView" AutoWidth="True" />
    </devxgrid:MyGrid.View>
 </devxgrid:MyGrid>
</StackPanel>

4 个答案:

答案 0 :(得分:4)

您正尝试在XAML中设置SelectedObject属性。如果它是只读的,你怎么设置它?

编辑:抱歉,我的不好。刚刚意识到你正在尝试做什么,你是对的,它应该工作。但是,WPF不支持这种情况,至少在3.5中。

编辑2:刚刚检查了.NET 4和同样的故事。

顺便说一句,如果您遇到其他人的只读DP,而您正试图“推送”到VM中,则可以使用附加行为来解决此问题。例如,假设您希望VM知道视图的ActualWidthActualHeight属性。您可以编写附加到SizeWatcherBehavior的{​​{1}}并监听大小更改。检测到时,这些大小更改将被推送到读取/写入VM可以绑定到的附加属性:

FrameworkElement

答案 1 :(得分:4)

考虑到差不多2年前的问题,我对这个问题有点迟了:)

我提出了一个动态解决方案,可以将只读依赖项属性推送到名为PushBinding的源blogged about hereDemo Project can be Downloaded Here。在你的情况下,它看起来像这样

<devxgrid:MyGrid AutoPopulateColumns="True"
                 DataSource="{Binding Animals}"
                 Width="300"
                 Height="300">
    <pb:PushBindingManager.PushBindings>
        <pb:PushBinding TargetProperty="SelectedObject" Path="MyObject"/> 
    </pb:PushBindingManager.PushBindings> 
    <!--...-->
</devxgrid:MyGrid> 

PushBinding使用两个依赖项属性,侦听器和镜像。侦听器绑定到OneWay到TargetProperty,并在PropertyChangedCallback中更新Mirror属性,该属性绑定OneWayToSource到绑定中指定的任何内容。

my WPF blog
它包含源代码和简短的样本用法,如果您对实现细节感兴趣,请访问{{3}}。

答案 2 :(得分:0)

我们正在开发一个自定义控件库,我们的一个用户提交了一个功能请求,将我们的一个DP从只读转换为读写,因为他确实遇到了与您相同的问题 - 无法绑定OneWayToSource一个MVVM场景。

当然我们没有让DP读写。

对这种情况使用附加属性/行为是一个巨大的开销。最简单的解决方法是在后面的代码中处理“SelectedObjectChanged”事件,并在后面的代码中设置要绑定到“SelectedObject”DP的属性。

在我们看来,这个'处理事件并直接从VM / DataContext调用代码'方法不会以任何方式破坏MVVM,因为ViewModel仍然不了解View。

答案 3 :(得分:0)

否则,我们中的纯粹主义者会期望真正的只读DependencyProperty场景应该按预期工作。但是对于明显的WPF单向和双向数据绑定期望,我同意这些观点。

但是,我通过提供完整的DependencyObject在我的DependencyProperty视图模型中解决了这个问题,但只提供了一个暴露我想要的详细信息的get-only属性。在WPF MVVM意义上不是真正的只读,但由于我选择不实现setter,它适用于我的目的。

我同意其他人的意见,除此之外,还有更严格意义上的MVVM。