【问题标题】:DependencyProperty on ViewModel of UserControl not updated by BindingUserControl 的 ViewModel 上的 DependencyProperty 未通过绑定更新
【发布时间】:2012-01-30 03:29:18
【问题描述】:

我有一个 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 的“系统”属性(以便它可以处理视图的数据),但该属性从未设置!

这是视图模型类中的依赖属性声明:

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

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

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

【问题讨论】:

  • 哪个疯子在虚拟机中有 DP?
  • 另外,您是如何确定该属性从未设置的?如果您在该设置器中设置断点,您将永远感到失望,因为绑定系统不使用它们。
  • @H.B 我稍后会检查视图(中断使用该属性的命令的处理程序)。我确实已经阅读过如何根据 wpf 的魔法跳过设置器。
  • 好吧,另一个未知数:绑定真的有效没有抛出binding errrors吗?这就是我在这里的怀疑。
  • 是的,除非我尝试 Mode=TwoWay (正如先前消失的答案所建议的那样),否则不会引发绑定错误。 Mode=TwoWay 的错误指定必须设置“Path or XPath”,即不能双向绑定到 DataTemplate 的 DataContext,这是有道理的。

标签: c# wpf xaml mvvm


【解决方案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>

是的,请不要那样做……

【讨论】:

  • 放弃目前的方法 - 看似不可能。感谢您的帮助。
  • @Andy:不客气,如果你有兴趣,我正在构建一个可怕的解决方法来娱乐。
  • @Andy:真的吗?好吧,我显然无法使用您的特定控件对此进行测试,因此它可能无法在每种情况下都有效...
【解决方案2】:

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

如果你真的想拦截设置动作,你可以通过你在初始化依赖属性时设置的回调来做到这一点。

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.
}

【讨论】:

  • 我之前曾尝试将 PropertyChangedCallback 添加到属性元数据并等待它被调用。它永远不会被调用(断点永远不会命中)!
  • @Andy - 在您之前的尝试中,该值是显式应用的还是通过绑定应用的?如果您显式设置值(我有 90% 的把握),它将使用您的属性设置器函数,但如果您使用绑定,则该回调将触发。
  • 通过绑定(根据提供的 sn-p)。还没试过明确设置。
猜你喜欢
  • 1970-01-01
  • 2017-06-13
  • 2012-09-17
  • 2011-05-18
  • 2012-06-06
  • 1970-01-01
  • 2011-10-27
  • 2010-11-23
相关资源
最近更新 更多