0

我在视图上有 10 个按钮,单击它们时应将 ViewModel 上的足够属性设置为 null(ViewModel 是 View 的 DataContext)。把它想象成一个重置动作。

目前我拥有的是 ViewModel 中的 ICommand,每个按钮的 Command 都绑定到,然后我将 CommandParameter 设置为某个值,这将允许我区分 ViewModel 上的哪些属性需要更新。

为了避免一堆如果,我正在考虑做这样的事情(语法不正确):

<Button ...>
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="Click">
      <Setter Property="PropertyA" Source="DataContext-ViewModel" Value="x:null" />
    </i:EventTrigger>
  <i:Interaction.Triggers>
</Button>

这有可能实现吗,如何实现?

4

1 回答 1

0

如果Reflection为您使用一个选项,那么您可以使用Reflection在 ViewModel 中设置属性。

你的命令执行方法会变成这样:

this.GetType().GetProperty((string)CommandParameter).SetValue(this, null, new object[] {});

但是,如果您更喜欢您在问题中提到的 XAML 路由,那么您可以创建一个TriggerAction并在EventTrigger. 以下是我尝试过的:

public sealed class SetProperty : TriggerAction<FrameworkElement>
{
    public static readonly DependencyProperty SourceProperty =
        DependencyProperty.Register("Source", typeof (object), typeof (SetProperty), new PropertyMetadata(default(object)));

    /// <summary>
    /// Source is DataContext
    /// </summary>
    public object Source
    {
        get { return (object) GetValue(SourceProperty); }
        set { SetValue(SourceProperty, value); }
    }

    public static readonly DependencyProperty PropertyNameProperty =
        DependencyProperty.Register("PropertyName", typeof (string), typeof (SetProperty), new PropertyMetadata(default(string)));

    /// <summary>
    /// Name of the Property
    /// </summary>
    public string PropertyName
    {
        get { return (string) GetValue(PropertyNameProperty); }
        set { SetValue(PropertyNameProperty, value); }
    }

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof (object), typeof (SetProperty), new PropertyMetadata(default(object)));

    /// <summary>
    /// Value to Set
    /// </summary>
    public object Value
    {
        get { return (object) GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    protected override void Invoke(object parameter)
    {
        if (Source == null) return;
        if (string.IsNullOrEmpty(PropertyName)) return;

        Source.GetType().GetProperty(PropertyName).SetValue(Source, Value, new object[] {});
    }
}

和 XAML:

<Button Content="Reset">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <local:SetProperty Source="{Binding}" PropertyName="PropertyToSet" Value="{x:Null}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

如果你根本不喜欢反射,那么你可以在你的视图模型中有一个动作字典:

_propertyResetters = new Dictionary<string, Action>
{
    {"PropertyToSet", () => PropertyToSet = null}
};

而且,在您的 Command Execute 方法中,您可以通过执行来调用这些操作_propertyResetters[(string)CommandParameter]();

希望这对您有所帮助或给您一些想法。

于 2013-11-06T15:35:44.060 回答