【问题标题】:What is the "proper" way in WPF MVVM to bind a frameworkElement event to a viewmodel handler?WPF MVVM中将frameworkElement事件绑定到viewmodel处理程序的“正确”方式是什么?
【发布时间】:2009-08-21 15:36:32
【问题描述】:

所以这是我的困境,我想在我的视图模型上处理视图事件,麻烦的是,为了添加一个事件处理程序,我的视图必须有一个代码隐藏文件,因此必须设置一个类属性。我 99% 确定这是一个坏主意,老实说,我什至不知道该怎么做(除了明显的 x:Class="" 部分) MVVM 应用程序?

<ResourceDictionary>
    <DataTemplate DataType="{x:Type vm:OutletViewModel}">
        <Button Click="IHaveNoBinding">
    </DataTemplate>
</ResourceDictionary>

【问题讨论】:

    标签: c# .net wpf events mvvm


    【解决方案1】:

    使用commands:

    <Button Command="{Binding ACommandOnYourViewModel}"/>
    

    请参阅我的this post,了解可以在视图模型中使用的有用命令实现。

    假设您不能使用命令,请使用attached command behaviors

    【讨论】:

    • 好吧,假设我不能使用命令,假设它是 Textbox.TextChanged
    • 对于文本,使用绑定:
    【解决方案2】:

    我使用附加行为。附加行为基本上将事件转化为命令。查看此链接以获取示例:

    http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx

    这是 TextChangedBehavior 的代码。

     public static class TextChangedBehavior
      {
        public static readonly DependencyProperty TextChangedCommandProperty =
            DependencyProperty.RegisterAttached("TextChangedCommand",
                                                typeof(ICommand),
                                                typeof(TextChangedBehavior),
                                                new PropertyMetadata(null, TextChangedCommandChanged));
    
        public static ICommand GetTextChangedCommand(DependencyObject obj)
        {
          return (ICommand)obj.GetValue(TextChangedCommandProperty);
        }
    
        public static void SetTextChangedCommand(DependencyObject obj, ICommand value)
        {
          obj.SetValue(TextChangedCommandProperty, value);
        }
    
        private static void TextChangedCommandChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
          TextBoxBase textBox = obj as TextBoxBase;
    
          if (textBox != null)
          {
            textBox.TextChanged += new TextChangedEventHandler(HandleTextChanged);
          }
        }
    
        private static void HandleTextChanged(object sender, TextChangedEventArgs e)
        {
          TextBox textBox = sender as TextBox;
          if (textBox != null)
          {
            ICommand command = GetTextChangedCommand(textBox);
            command.Execute(textBox.Text);
          }
        }
      }
    

    XAML:

    <TextBox behavior:TextChangedBehavior.TextChangedCommand="{Binding TextChangedCommand}" />
    

    【讨论】:

      【解决方案3】:

      一般来说,我不会将附加的行为模式用于像这样的简单事情。作为一名顾问,我发现它使新开发人员的事情变得复杂。

      那么,当没有可用的命令时,如何处理控件交互。准备好从地板上站起来 :-) 我经常会为此使用背后的代码。后面代码中的事件处理程序处理事件,它从事件参数中收集它需要的任何数据,然后将请求转发到视图模型。这样做不会损失太多,因为大多数不支持 ICommand 的东西无论如何都无法利用隐藏/显示/启用/禁用。

      但是有一些规则。后面的代码只能用于控制转发到 View Model。只要您不将事件参数直接传递给视图模型,我认为以这种方式使用事件就可以了。事实上,在大型应用程序中,您总是无法摆脱代码背后的问题。如果您按预期使用它们,即页面控件,我认为这样做没有害处。

      【讨论】:

        【解决方案4】:

        代码背后并不是一件坏事。有足够多的场景您不能使用 WPF 数据绑定(例如 PasswordBox),然后您必须创建一个代码隐藏文件。

        如何在不绑定的情况下使用 PasswordBox 显示在该项目的 ViewModel 示例中:

        WPF 应用程序框架 (WAF)

        http://waf.codeplex.com

        【讨论】:

          猜你喜欢
          • 2016-02-03
          • 2012-06-11
          • 1970-01-01
          • 2010-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-07
          • 2011-06-10
          相关资源
          最近更新 更多