XAML Binding.UpdateSourceTrigger при запуске Button.Click?

Я хочу установить UpdateSourceTrigger на событие элемента управления:

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

Я думал о двух способах:

  1. Установите UpdateSourceMode или что-то еще в привязке.
  2. Установите EventTrigger, который обновляет источник при нажатии кнопки.

Возможно, или я должен сделать это с помощью кода?


person Shimmy Weitzhandler    schedule 23.08.2009    source источник


Ответы (3)


Вам придется использовать код. Конкретно:

  1. Установите UpdateSourceTrigger=Explicit на TextBox.
  2. Вызывать UpdateSource, когда пользователь щелкает Button.

Однако вы можете поместить код в код позади или в прикрепленное поведение. .

person Kent Boogaart    schedule 23.08.2009
comment
Кент, у меня есть способ сделать это Xamly? Поскольку у меня есть огромное количество текстовых полей в моей форме, и я хочу, чтобы, когда пользователь нажимает «Сохранить», он обновлял исходный код, я не хочу получать все BE и обновлять их один за другим. - person Shimmy Weitzhandler; 20.01.2010
comment
Думаю, я буду использовать BindingGroup.UpdateSources(). - person Shimmy Weitzhandler; 21.01.2010
comment
Нет встроенного способа, о котором я знаю. Но, как я уже сказал, вы можете написать собственное прикрепленное поведение, которое делает это. - person Kent Boogaart; 21.01.2010

Я знаю, что это было давно, но я столкнулся с той же проблемой и хочу поделиться своим решением. Надеюсь, это будет полезно для кого-то.

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;
}
person 0xbadf00d    schedule 01.06.2011

Вот мое решение:

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 в примере кода).

person Petryk    schedule 01.02.2018