如何创建/使用在读取时生成其值的DependencyProperty?

时间:2017-02-06 14:36:45

标签: wpf generator dependency-properties

我想创建一个DependencyProperty,每次读取时都会生成一个值;例如类似的东西:

private static Random _rng = new Random();

public int RandomNumber
{
    get
    {
        int x = _rng.Next();
        SetValue(RandomNumberProperty, x);
        return x;
    }
}
private static readonly DependencyPropertyKey RandomNumberProperty = DependencyProperty.RegisterReadOnly(nameof(RandomNumber), typeof(int), typeof(Window1), new PropertyMetadata(-1));

并使用此属性填充CommandParameter; e.g:

public static RoutedUICommand CmdRandomNumber = new RoutedUICommand() { Text = "Use a random number supplied as parameter." };

private void ExecuteShowMessage(object sender, ExecutedRoutedEventArgs e)
{
    MessageBox.Show($"And the winner is ... {(int)e.Parameter}" );
}

private void CanExecuteShowMessage(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true;
}

并在XAML中:

<Window DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Window.CommandBindings>
        <CommandBinding Command="{x:Static local:Window1.CmdRandomNumber}"
                        Executed="ExecuteShowMessage"
                        CanExecute="CanExecuteShowMessage" />
        </CommandBinding>
    </Window.CommandBindings>
    <Button Command="{x:Static local:Window1:CmdRandomNumber}"
            CommandParameter="{Binding RandomNumber}"/>
</Window>

但是,这不起作用:ExecuteShowMessage始终收到初始值。可能由于DependencyProperty未收到有关值更改的通知以及请求DependencyProperty的值时,它会返回其缓存值,而不是从RandomNumber检索它。

我想将不同的参数绑定到不同的按钮,并且每个按钮执行相同的命令;因此,我尝试使用CommandParameters而非RandomValue内的ExecuteShowMessage

如何实现可在WPF数据绑定中使用的属性,每次读取时都会生成其值?如何确保读取其支持权限而不是依赖于其缓存值的DependencyProperty? (特别是在CommandParameters的背景下。)

1 个答案:

答案 0 :(得分:1)

  

如何实现可在WPF数据绑定中使用的属性   每次读取时都会产生它的值?

WPF Binding的source属性可以是普通的CLR属性,如下所示:

public int RandomNumber
{
    get { return _rng.Next(); }
}

如果您需要强制更新Binding以读取新的属性值,拥有该属性的类可以实现INotifyPropertyChanged接口,并在必要时触发PropertyChanged事件,如:

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("RandomNumber"));