触发Button.Click时XAML Binding.UpdateSourceTrigger?

时间:2009-08-23 03:42:19

标签: wpf xaml binding triggers eventtrigger

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

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

我想到了两种方式:

  1. 在绑定中设置UpdateSourceMode或其他一些内容。
  2. 设置一个EventTrigger,在点击按钮时更新源。
  3. 可能,或者我必须使用代码吗?

3 个答案:

答案 0 :(得分:1)

您必须使用代码。具体做法是:

  1. UpdateSourceTrigger=Explicit上设置TextBox
  2. 当用户点击Button
  3. 时,请致电UpdateSource

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

答案 1 :(得分:1)

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

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;
}

答案 2 :(得分:1)

这是我的解决方案:

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)非常重要。