首页 文章

传播DependencyProperty默认值

提问于
浏览
1

我有一个带ViewModel的WPF UserControl:

<MyUserControl ...>
    <Grid Name="UxRootContainer">
        <Grid.DataContext>
            <MyViewModel/>
        </Grid.DataContext>
    </Grid>
</MyUserControl>

此UserControl具有DependencyProperty,必须传播到ViewModel:

public static readonly DependencyProperty DurationProperty = 
     DependencyProperty.Register( "Duration", typeof(TimeSpan),
     typeof(MyUserControl), new FrameworkPropertyMetadata(TimeSpan.FromHour(1), OnDurationChanged ));

public TimeSpan Duration
{
    get { return (TimeSpan)GetValue(DurationProperty); }
    set { SetValue(DurationProperty, value); }
}

private static void OnDurationChanged(DependencyObject source, 
        DependencyPropertyChangedEventArgs e)
{
    MyUserControl control = source as MyUserControl;
    TimeSpan duration = (TimeSpan)e.NewValue;
    control.UxRootContainer.SetDuration(duration);
}

这工作正常,但我们不会在 OnDurationChanged 事件中收到默认值 .

我知道我可以在构造函数中自己调用此方法,将默认持续时间设置为常量,但是:

  • 我要为每个DependencyProperty创建一个常量

  • 即使最后我不使用默认值,我也必须调用它

关于如何将默认值传播到ViewModel的任何好建议,仅当默认值是最后使用的值(不是其他值集)时 .

2 回答

  • 1

    除了我们不会在OnDurationChanged事件中收到默认值

    让该类遵循 INotifyPropertyChanged 然后让VM(或任何需要该信息)订阅该控件的事件 . 这样当它发生变化时(或者设置了值),就会通知消费者 .

    看到这个回答这个问题How To Raise Property Changed events on a Dependency Property?

    关于如何将默认值传播到ViewModel的任何好建议,仅当默认值是最后使用的值(而不是其他值集)时 .

    您描述了需要编码的业务逻辑,以确定是否正在使用默认值 . 如果没有上述逻辑,您的请求就可以完成 .


    发生的事情是竞争条件 . 控件不能绑定通知更改不存在的东西...控件的创建首先发生,默认值设置为秒,然后您的控件绑定到它,所有这些都在运行时 . 操作在设计时设置,但这不会影响过程本身 .

  • 3

    我决定写一个答案(看看我错了:) .

    在给定的情况下,您正在创建自定义控件,这意味着在其他视图中是一个简单的控件 . 两点:

    • 不创建ViewModel;

    • 不设置此控件的 DataContext .

    在这种情况下,ViewModel不起任何作用:没有要抽象的底层模型,任何(不是View,也不是ViewModel)都将被重用 . 如果没有ViewModel,则默认值已经是依赖属性=问题解决的默认值 .

    至于 DataContext :如果您尝试在列表中使用此控件将项属性绑定到它,您将始终必须通过父容器 DataContext 引用它(因为控件具有其覆盖并且绑定 "{Binding Text}" 将不会引用该项 Text 属性,但是控制ViewModel Text属性,你必须做 "{Binding DataContext.Text, RelativeSource={RelativeSource FindAncestor, AncestorType=Grid}}" 这样的事情 . 这在任何设计中都是不对的 .

相关问题