Binding XAML默认按钮调用和绑定

Binding XAML默认按钮调用和绑定,binding,Binding,当然我做错了什么,但是,我不知道是什么 我在WPF用户控件中有一个默认按钮,如下所示: <Button Name="btnProcessar" Width="80" Height="24" Click="btnProcessar_Click" Content="_Buscar" ToolTip="Buscar" IsDefault="True"/> <TextB

当然我做错了什么,但是,我不知道是什么

我在WPF用户控件中有一个默认按钮,如下所示:

<Button Name="btnProcessar" 
        Width="80"
        Height="24"
        Click="btnProcessar_Click"
        Content="_Buscar"
        ToolTip="Buscar" 
        IsDefault="True"/>
        <TextBox Name="txtCodigo" 
                 Width="100"
                 Height="26"
                 Margin="5,0,0,0"
                 MaxLength="8"
                 ToolTip="Preencher com parte do código do Serviço Composto buscado.">
            <Binding Mode="TwoWay" Path="TarefaBuscarServicosCompostos.Codigo" />
        </TextBox>

网格中的第一个控件是文本框,如下所示:

<Button Name="btnProcessar" 
        Width="80"
        Height="24"
        Click="btnProcessar_Click"
        Content="_Buscar"
        ToolTip="Buscar" 
        IsDefault="True"/>
        <TextBox Name="txtCodigo" 
                 Width="100"
                 Height="26"
                 Margin="5,0,0,0"
                 MaxLength="8"
                 ToolTip="Preencher com parte do código do Serviço Composto buscado.">
            <Binding Mode="TwoWay" Path="TarefaBuscarServicosCompostos.Codigo" />
        </TextBox>

不要在意路径,只要知道,
TarefaBuscarServicosCompostos
是我的虚拟机(某种)。当我在文本框有焦点的情况下按键盘上的enter键时,单击事件按预期启动,因此我可以检查(通过调试)是否调用了
btnProcessar\u Click

问题在于束缚;您知道,在引发事件时,TarefaBuscarServicosCompostos.Codigo没有数据。我很清楚,WPF在调用代码来处理事件之前并没有解析绑定

  • 为什么呢?在调用
    btnProcessar\u Click
    之前,是否应该评估所有绑定
  • 是否有办法强制WPF从
    btnProcessar\u单击
    评估绑定
  • 有没有更好的办法解决这个问题?在使用绑定的同时,我应该如何处理事件

  • 非常感谢。当然,我们非常感谢您的帮助。

    您有多种选择。最简单的方法是将绑定的属性设置为
    UpdateSourceTrigger=Property
    。另一种可能是在
    btnProcessar
    over

    中手动执行绑定。我已经想出了解决此问题的另一种方法。对于那些不想更改表单上每一个绑定(甚至不想创建一个新的绑定类)的用户,可以在用户控件窗口(或任何其他内容控件)上使用以下附加属性,使默认按钮在命令执行之前处于焦点。并解决了绑定问题

    public class DefaultButtonBehavior
    {
        private static readonly DependencyProperty EnableProperty = DependencyProperty.RegisterAttached(
        "Enable", typeof(bool), typeof(ContentControl), new PropertyMetadata(false, PropertyChangedCallback));
        public static void SetEnable(DependencyObject obj, bool value)
        {
            obj.SetValue(EnableProperty, value);
        }
    
        public static bool GetEnable(DependencyObject obj)
        {
            return (bool)obj.GetValue(EnableProperty);
        }
    
        private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            var control = dependencyObject as ContentControl;
            if (control == null)
                return;
    
            control.Loaded += (sender, args) =>
            {
                var depthStack = new Stack<int>();
                var index = 0;
                var parent = dependencyObject;
                while (depthStack.Count > 0 || index < VisualTreeHelper.GetChildrenCount(parent))
                {
                    while (index == VisualTreeHelper.GetChildrenCount(parent) && depthStack.Count > 0)
                    {
                        parent = VisualTreeHelper.GetParent(parent);
                        index = depthStack.Pop();
                    }
    
                    if (index == VisualTreeHelper.GetChildrenCount(parent))
                        break;
    
                    var child = VisualTreeHelper.GetChild(parent, index);
                    if (child is Button)
                        if(((Button)child).IsDefault)
                        ((Button)child).Click += ButtonOnClick;
    
                    if (VisualTreeHelper.GetChildrenCount(child) > 0)
                    {
                        parent = child;
                        index++;
                        depthStack.Push(index);
                        index = 0;
                    }
                    else
                        index++;
                }
            };
        }
    
        private static void ButtonOnClick(object sender, RoutedEventArgs routedEventArgs)
        {
            var button = sender as Button;
    
            button?.Focus();
        }
    }
    
    public类DefaultButtonBehavior
    {
    私有静态只读DependencyProperty EnableProperty=DependencyProperty.RegisterAttached(
    “Enable”、typeof(bool)、typeof(ContentControl)、newpropertymetadata(false、PropertyChangedCallback));
    公共静态void SetEnable(DependencyObject对象,布尔值)
    {
    对象设置值(EnableProperty,value);
    }
    公共静态bool GetEnable(DependencyObject obj)
    {
    返回(bool)对象GetValue(EnableProperty);
    }
    私有静态无效属性ChangedCallback(DependencyObject DependencyObject,DependencyPropertyChangedEventArgs DependencyPropertyChangedEventArgs)
    {
    var control=作为ContentControl的dependencyObject;
    if(control==null)
    回来
    控件。已加载+=(发送方,参数)=>
    {
    var depthStack=新堆栈();
    var指数=0;
    var parent=dependencyObject;
    while(depthStack.Count>0 | | index0)
    {
    父级=VisualTreeHelper.GetParent(父级);
    index=depthStack.Pop();
    }
    if(索引==VisualTreeHelper.GetChildrenCount(父级))
    打破
    var child=VisualTreeHelper.GetChild(父级,索引);
    如果(子对象是按钮)
    if(((按钮)子项).IsDefault)
    ((按钮)子项)。单击+=按钮单击;
    如果(VisualTreeHelper.GetChildrenCount(子项)>0)
    {
    父母=子女;
    索引++;
    深度堆栈推送(索引);
    指数=0;
    }
    其他的
    索引++;
    }
    };
    }
    私有静态无效按钮非单击(对象发送方,RoutedEventArgs RoutedEventArgs)
    {
    var按钮=发送方为按钮;
    按钮?.Focus();
    }
    }
    
    你可以这样使用它

    <UserControl
            ...
            common:DefaultButtonBehavior.Enable="True">
            .
            .
            .
            <Button Command="{Binding SaveCommand}" 
                    IsDefault="True"
                    ...
                     />
    </UserControl>
    
    
    .
    .
    .