【问题标题】:How to implement IsEnabledChanged of silverlight dataform using MVVM如何使用 MVVM 实现 Silverlight 数据表单的 IsEnabledChanged
【发布时间】:2012-02-14 18:27:31
【问题描述】:

我正在寻找一个如何使用 MVVM light 实现数据表单的属性 IsEnabledChanged 的​​示例,我设置了触发器但不确定实现。所以,这是版本背后的代码:

  void DataForm_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        if (!IsEnabled)
        {
            VisualStateManager.GoToState(DataForm, "Disabled", true);
        }
        else
        {
            VisualStateManager.GoToState(DataForm, "Normal", true);
        }
    }

DataForm.IsEnabledChanged += new DependencyPropertyChangedEventHandler(DataForm_IsEnabledChanged);

在 xaml 中使用 MVVM light 我这样做了:

 <i:EventTrigger EventName="IsEnabledChanged">
                    <cmdextras:EventToCommand Command="{Binding IsEnabledChangedCommand}" CommandParameter="{Binding .}" />
                </i:EventTrigger>

现在,需要弄清楚如何翻译后面的代码来使用relay命令。

【问题讨论】:

  • 你能告诉我们你到目前为止的代码吗?
  • 您的代码隐藏有什么问题?如果它有效 - 为什么要改变它?您正在执行的代码与您的视图紧密耦合。不需要涉及视图模型。

标签: silverlight mvvm mvvm-light


【解决方案1】:

我创建了一个与数据表单的 EditStarted 事件类似的行为。

public class EditableDataFormBehavior : Behavior<RadDataForm>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.Loaded += AssociatedObject_Loaded;
    }

    void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
        AssociatedObject.CurrentItemChanged += AssociatedObject_CurrentItemChanged;
    }

    void AssociatedObject_CurrentItemChanged(object sender, EventArgs e)
    {
        var editableObject = AssociatedObject.CurrentItem as INotifyEditableObject;
        if (editableObject != null)
        {
            editableObject.EditStarted += Object_EditStarted;
        }
    }

    void Object_EditStarted(object sender, EventArgs e)
    {
        AssociatedObject.BeginEdit();
    }

    protected override void OnDetaching()
    {
        // detach the event handler
        AssociatedObject.Loaded -= AssociatedObject_Loaded;
        AssociatedObject.CurrentItemChanged -= AssociatedObject_CurrentItemChanged;

        var editableObject = AssociatedObject.DataContext as INotifyEditableObject;
        if(editableObject!=null)
            editableObject.EditStarted -= Object_EditStarted;
        base.OnDetaching();
    }


}

您只需要通过附加到 IsEnabledChanged 事件来稍作修改。您正在尝试实现仅视图行为,而视图模型应该对此一无所知。这样做的主要好处是它比后面的代码更可重用。

在事件处理程序中,您将添加您的代码:

    if (!IsEnabled)
    {
        VisualStateManager.GoToState(DataForm, "Disabled", true);
    }
    else
    {
        VisualStateManager.GoToState(DataForm, "Normal", true);
    }

将行为附加到数据表单(我的是为 Telerik 制作的,但应该可以使用 sdk)

 <i:Interaction.Behaviors>
                <utilities:EditableDataFormBehavior/>
 </i:Interaction.Behaviors>

【讨论】:

  • 嗨,我很想试试这个行为,让你知道它是如何工作的。
【解决方案2】:

EventTrigger 仅处理 routed events (see documentation)。当您处理 dependency property changed event 时,EventTrigger 根本无法识别它。

所以从我所见,使用后面的代码是实现所需功能的唯一方法。此外,您正在处理属于视图并绑定到您正在使用的控件的功能(在这种情况下为DataForm)。因此,将这种依赖关系拉入视图模型会适得其反,因为视图模型应该独立于任何给定的视图实现 - 即目标是设计您的视图模型,以便它可以独立于视图和其中使用的控件。

【讨论】:

  • 感谢您的解释。我将首先尝试 SalieHendrix 提供的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 2014-08-16
  • 1970-01-01
  • 2012-01-07
  • 1970-01-01
相关资源
最近更新 更多