UserControl的ViewModel上的DependencyProperty未由Binding更新

时间:2012-01-30 03:29:19

标签: c# wpf xaml mvvm

我有一个UserControl,用作ItemsControl中项目的基础:

主页xaml:

<ItemsControl ItemsSource="{Binding Systems, Mode=TwoWay}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:ServerGroupControl>
                <local:ServerGroupControl.DataContext>
                    <local:ServerGroupControlViewModel System="{Binding}"/>
                </local:ServerGroupControl.DataContext>
            </local:ServerGroupControl>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

我正在尝试设置每个ViewModel的'System'属性(这样它可以处理视图的数据),但该属性永远不会被设置!

以下是视图模型类中的dependancy属性声明:

    public static readonly DependencyProperty SystemProperty = DependencyProperty.Register(
        "System",
        typeof(ServerGroup),
        typeof(ServerGroupControlViewModel)
    );

    public ServerGroup System
    {
        get { return (ServerGroup)GetValue(SystemProperty); }
        set { SetValue(SystemProperty, value); }
    }

该属性始终保持默认值。关于为什么这个设置不起作用的任何想法?

2 个答案:

答案 0 :(得分:1)

因此,基于您的评论,我会怀疑绑定不起作用,因为您尝试绑定的地方没有DataContext

你的虚拟机不是FrameworkElement所以它没有DataContext属性,可能它也不是Freezable(因此也可能缺少继承上下文)所以我怀疑它赢了不行。 (顺便说一下,ElementNameRelativeSource将不起作用

我建议您采用不同的方式,但由于线程关联性和其他问题,我不建议在VM中使用DP。


这是一个解决方案的一个宝石:

<DataTemplate>
    <local:ServerGroupControl Name="sgc">
        <local:ServerGroupControl.Resources>
            <local:ServerGroupControlViewModel x:Key="context"
                System="{Binding Parent.DataContext, Source={x:Reference sgc}}" />
        </local:ServerGroupControl.Resources>
        <local:ServerGroupControl.DataContext>
            <StaticResource ResourceKey="context" />
        </local:ServerGroupControl.DataContext>
    </local:ServerGroupControl>
</DataTemplate>

是的,请不要那样做......

答案 1 :(得分:0)

通过数据绑定设置属性时,不会调用显式setter函数。

如果您确实要拦截设置操作,可以通过初始化依赖项属性时设置的回调来执行此操作。

public static readonly DependencyProperty SystemProperty = DependencyProperty.Register(
        "System",
        typeof(ServerGroup),
        typeof(ServerGroupControlViewModel),
        new PropertyMetadata
        {
            PropertyChangedCallback = SystemPropertyChanged
        }
    );


static void SystemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ServerGroupControlViewModel receiver = (ServerGroupControlViewModel)d;
    ServerGroup newValue = e.NewValue as ServerGroup;

    // Add any appropriate handling logic here.
}