【问题标题】:XAML Binding.UpdateSourceTrigger when a Button.Click is fired?触发 Button.Click 时的 XAML Binding.UpdateSourceTrigger?
【发布时间】:2009-08-23 03:42:18
【问题描述】:

我想将 UpdateSourceTrigger 设置为控件的事件:

<TextBox Text="{Binding Field, UpdateSourceMode=btnOK.Click}">
<Button Name="btnOK">
    <Button.Triggers>
        <Trigger>
            <!-- Update source -->
        </Trigger>
    </Button.Triggers>
</Button>

我想到了两种方法:

  1. 在绑定中设置 UpdateSourceMode 或其他一些东西。
  2. 设置一个 EventTrigger,在点击按钮时更新源。

可能,还是我必须用代码来做?

【问题讨论】:

    标签: wpf xaml binding triggers eventtrigger


    【解决方案1】:

    您必须使用代码。具体来说:

    1. TextBox 上设置UpdateSourceTrigger=Explicit
    2. 当用户点击Button时调用UpdateSource

    但是,您可以将代码放在代码后面或attached behavior 中。

    【讨论】:

    • 肯特,我有办法 Xamly 吗?因为我的表单中有大量的文本框,并且我希望当用户单击“保存”时它应该更新源,我不想获取所有 BE 并一一更新。
    • 我想我会使用 BindingGroup.UpdateSources()。
    • 没有我知道的内置方式。但就像我说的,你可以编写自己的附加行为来做到这一点。
    【解决方案2】:

    我知道这已经有一段时间了,但我遇到了同样的问题并想分享我的解决方案。希望对某人有所帮助。

    public class UpdateSourceBehavior : Behavior<System.Windows.Interactivity.TriggerBase>
    {
        internal const string TargetElementPropertyLabel = "TargetElement";
    
    
        static UpdateSourceBehavior()
        {
            TargetElementProperty = DependencyProperty.Register
            (
                TargetElementPropertyLabel,
                typeof(FrameworkElement),
                typeof(UpdateSourceBehavior),
                new PropertyMetadata(null)
            );
        }
    
    
        public static readonly DependencyProperty TargetElementProperty;
    
    
        [Bindable(true)]
        public FrameworkElement TargetElement
        {
            get { return (FrameworkElement)base.GetValue(TargetElementProperty); }
            set { base.SetValue(TargetElementProperty, value); }
        }
    
        public PropertyPath TargetProperty { get; set; }
    
    
        protected override void OnAttached()
        {
            base.OnAttached();
    
            this.InitializeMembers();
            base.AssociatedObject.PreviewInvoke += this.AssociatedObject_PreviewInvoke;
        }
    
        protected override void OnDetaching()
        {
            base.AssociatedObject.PreviewInvoke -= this.AssociatedObject_PreviewInvoke;
            base.OnDetaching();
        }
    
    
        private void AssociatedObject_PreviewInvoke(object sender, PreviewInvokeEventArgs e)
        {
            this.m_bindingExpression.UpdateSource();
        }
    
    
        private void InitializeMembers()
        {
            if (this.TargetElement != null)
            {
                var targetType = this.TargetElement.GetType();
                var fieldInfo = targetType.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
                                          .FirstOrDefault(fi => fi.Name == this.TargetProperty.Path + "Property");
    
                if (fieldInfo != null)
                    this.m_bindingExpression = this.TargetElement.GetBindingExpression((DependencyProperty)fieldInfo.GetValue(null));
                else
                    throw new ArgumentException(string.Format("{0} doesn't contain a DependencyProperty named {1}.", targetType, this.TargetProperty.Path));
            }
            else
                throw new InvalidOperationException("TargetElement must be assigned to in order to resolve the TargetProperty.");
        }
    
    
        private BindingExpression m_bindingExpression;
    }
    

    【讨论】:

      【解决方案3】:

      这是我的解决方案:

      XAML:

      <StackPanel>
        <i:Interaction.Triggers>
          <i:EventTrigger SourceName="submit" EventName="Click">
            <behaviours:TextBoxUpdateSourceAction TargetName="searchBox"></behaviours:TextBoxUpdateSourceAction>
          </i:EventTrigger>
        </i:Interaction.Triggers>
        <TextBox x:Name="searchBox">
          <TextBox.Text>
            <Binding Path="SomeProperty" UpdateSourceTrigger="Explicit" NotifyOnValidationError="True">
              <Binding.ValidationRules>
                <DataErrorValidationRule ValidatesOnTargetUpdated="False"/>
              </Binding.ValidationRules>
            </Binding>
          </TextBox.Text>
        </TextBox>
        <Button x:Name="submit"></Button>
      </StackPanel>
      

      行为定义(继承自TargetedTriggerAction):

      public class TextBoxUpdateSourceAction : TargetedTriggerAction<TextBox>
      {
          protected override void Invoke(object parameter)
          {
              BindingExpression be = Target.GetBindingExpression(TextBox.TextProperty);
              be.UpdateSource();
          }
      }
      

      请注意,将 TextBoxUpdateSourceAction 附加到父容器(示例代码中的 StackPanel)非常重要。

      【讨论】:

        猜你喜欢
        • 2012-05-06
        • 1970-01-01
        • 2011-03-05
        • 2013-06-19
        • 1970-01-01
        • 2011-01-22
        • 1970-01-01
        • 2011-08-22
        • 1970-01-01
        相关资源
        最近更新 更多