wpf - 在带有默认按钮的对话框上按 Enter 时,数据绑定(bind)不会更新属性

标签 wpf data-binding mvvm

我的设置如下所述:

  • WPF 4 应用程序
  • MVVM Lite 框架
  • “添加项目”窗口以对话模式显示在主窗口的顶部(使用 view.ShowDialog();)
  • 该对话框有许多输入字段,以及将 IsDefault 属性设置为 True 的“保存”按钮
  • “保存”按钮是通过绑定(bind)到命令
  • 来处理的。
  • 数据绑定(bind)在 View XAML 中的输入字段和 ViewModel 中的相应属性之间定义(一种方式,UI 更新 ViewModel,Mode=OneWayToSource)

  • 问题是当我在键盘上按 Enter 时,我在最后一个输入字段中提供的值不会推送到 ViewModel 的底层属性。

    我怀疑这与输入字段在窗口关闭之前没有失去焦点的事实有关(因此所有绑定(bind)都“解散”)。
    为了比较,如果我单击“保存”按钮(而不是让其单击由 Enter 上的窗口处理),则属性中的值将更新。
    此外,如果我向按钮的 Click 事件添加(恐怖!恐怖!)事件处理程序,并在代码隐藏中调用 button.Focus(),一切正常!

    有什么办法可以补救?

    我显然不想处理任何窗口关闭事件,并“手动”获取缺失值......这将违反整个 MVVM 概念:-(

    有更好的建议吗?

    谢谢,
    亚历克斯

    最佳答案

    默认情况下,TextBox仅在失去焦点后通知其来源其值已更改。您可以通过设置 UpdateSourceTrigger=PropertyChanged 在绑定(bind)中更改它。 .这将使 TextBox 向其源发送更新通知,它的 Text 被更改,而不是仅在失去焦点时。

    如果您不想在任何时候按下某个键时发送更新通知,您可以创建一个 AttachedProperty如果按下 Enter 键,则更新源。

    这是我用于此类情况的 AttachedProperty:

    // When set to True, Enter Key will update Source
    #region EnterUpdatesTextSource DependencyProperty
    
    // Property to determine if the Enter key should update the source. Default is False
    public static readonly DependencyProperty EnterUpdatesTextSourceProperty =
        DependencyProperty.RegisterAttached("EnterUpdatesTextSource", typeof (bool),
                                            typeof (TextBoxHelper),
                                            new PropertyMetadata(false, EnterUpdatesTextSourcePropertyChanged));
    
    // Get
    public static bool GetEnterUpdatesTextSource(DependencyObject obj)
    {
        return (bool) obj.GetValue(EnterUpdatesTextSourceProperty);
    }
    
    // Set
    public static void SetEnterUpdatesTextSource(DependencyObject obj, bool value)
    {
        obj.SetValue(EnterUpdatesTextSourceProperty, value);
    }
    
    // Changed Event - Attach PreviewKeyDown handler
    private static void EnterUpdatesTextSourcePropertyChanged(DependencyObject obj,
                                                              DependencyPropertyChangedEventArgs e)
    {
        var sender = obj as UIElement;
        if (obj != null)
        {
            if ((bool) e.NewValue)
            {
                sender.PreviewKeyDown += OnPreviewKeyDownUpdateSourceIfEnter;
            }
            else
            {
                sender.PreviewKeyDown -= OnPreviewKeyDownUpdateSourceIfEnter;
            }
        }
    }
    
    // If key being pressed is the Enter key, and EnterUpdatesTextSource is set to true, then update source for Text property
    private static void OnPreviewKeyDownUpdateSourceIfEnter(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            if (GetEnterUpdatesTextSource((DependencyObject) sender))
            {
                var obj = sender as UIElement;
                BindingExpression textBinding = BindingOperations.GetBindingExpression(
                    obj, TextBox.TextProperty);
    
                if (textBinding != null)
                    textBinding.UpdateSource();
            }
        }
    }
    
    #endregion //EnterUpdatesTextSource DependencyProperty
    

    关于wpf - 在带有默认按钮的对话框上按 Enter 时,数据绑定(bind)不会更新属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7366797/

    相关文章:

    c# - 在 WPF 中查找字形的像素大小

    Service 中的 Android ViewModel(备选)

    c# - WPF , MVVM , MasterDetailPage , 设计

    wpf databinding datatrigger 为矩形设置动画

    c# - 使用 WPF 在 3d 中绘制大型数据集?

    vue.js - v-model 触发更改事件两次

    c# - 如何使用 Telerik Rad 网格绑定(bind)将数据传递给 Ajax 服务?

    android - 在文件 '/activity_login.xml' DataBinding 中发现重复的类,未生成 BR

    c# - 我可以同时使用 PropertyChanged 和 LostFocus 吗?

    c# - WPF 用户控件子级不更新 c#