【问题标题】:MVVM and Prism - How to handle TextBox_DragEnter and TextBox_Drop Events in ViewModelMVVM 和 Prism - 如何在 ViewModel 中处理 TextBox_DragEnter 和 TextBox_Drop 事件
【发布时间】:2016-12-23 11:34:44
【问题描述】:

我正在学习 MVVM 和 PRISM,并尝试处理 TextBox 的 Drop 和 DragEnter 事件。

我已经成功地完成了一个按钮点击

    public ButtonsViewModel()
    {
        //If statement is required for viewing the MainWindow in design mode otherwise errors are thrown
        //as the ButtonsViewModel has parameters which only resolve at runtime. I.E. events
        if (!(bool)DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue)
        {
            svc = ServiceLocator.Current;
            events = svc.GetInstance<IEventAggregator>();
            events.GetEvent<InputValidStatus>().Subscribe(SetInputStatus);
            StartCommand = new DelegateCommand(ExecuteStart, CanExecute).ObservesProperty(() => InputStatus);
            ExitCommand = new DelegateCommand(ExecuteExit);
        }
    }

    private bool CanExecute()
    {
        return InputStatus;
    }

    private void ExecuteStart()
    {
        InputStatus = true;
        ERA Process = new ERA();
        Proces.Run();
    }

这可以正常工作,并且对于不采用 EventArgs 的其他事件执行此操作没有问题。所以 Drop 方法可以很好地实现,因为我不需要与 EventArgs 交互。

然而,通过 Textbox_DragEnter 事件,它会设置 TextBox 的 DragDropEffects

    private void TextBox_DragEnter(object sender, DragEventArgs e)
    {
        e.Effects = DragDropEffects.Copy;
    }

我的第一个想法是创建一个 ICommand 并将其绑定到 TextBox_DragEnter 事件,并在 ViewModel 中为此更新 DragDropEffects 属性。但我看不到如何将效果绑定到文本框。

我可能想错了。这样做的正确方法是什么?

我知道我可以在后面的代码中轻松设置这些事件,但我不希望这样做,而是纯粹使用 MVVM 模式来保持它

希望这是有道理的。

【问题讨论】:

  • 我认为是给事件添加了属性,然后将这些属性中的事件参数传递给了ViewModel
  • 你是怎么做到的?
  • 是的,我没有找到更好的解决方案

标签: c# wpf mvvm event-handling prism


【解决方案1】:

对此的另一种交互触发解决方案,类似于 Kevin 提出的方案,但这将适用于 Prism(非 MVVMLight 解决方案)。

需要命名空间:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

XAML:

<TextBox Name="TextBox" Text="{Binding MVFieldToBindTo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="DragEnter">
            <i:InvokeCommandAction 
                Command="{Binding BoundCommand}" 
                CommandParameter="{Binding Text, ElementName=TextBox}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>

BoundCommand 将是视图模型中的 DelegateCommand。看起来你已经很清楚那是什么了。这是使用 DragEnter 编写的,但在实践中我只将其用于 LostFocus 事件,因此您可能需要稍微尝试一下。它应该能让你朝着正确的方向前进。

【讨论】:

【解决方案2】:

您可以使用交互事件触发器在视图模型中触发命令。例如下面我将命令 X 连接到 RowActivated 事件。这使用了 MVVMLight EventToCommand 助手。将此代码放入您的控件中

<i:Interaction.Triggers>
      <i:EventTrigger EventName="RowActivated">
           <commands:EventToCommand Command="{Binding X}" PassEventArgsToCommand="True"/>
      </i:EventTrigger>
</i:Interaction.Triggers>

你需要的命名空间是

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:commands="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras"

【讨论】:

    【解决方案3】:

    查看GongSolutions.WPF.DragDrop,了解易于使用的支持 MVVM 的拖放框架。

    【讨论】:

      猜你喜欢
      • 2014-01-23
      • 1970-01-01
      • 2017-07-01
      • 1970-01-01
      • 2019-09-18
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 2013-08-05
      相关资源
      最近更新 更多