XAML Binding.UpdateSourceTrigger wenn ein Button.Click gebrannt?
-
19-09-2019 - |
Frage
Ich möchte das Update auf ein Ereignis einer Steuerung einzustellen:
<TextBox Text="{Binding Field, UpdateSourceMode=btnOK.Click}">
<Button Name="btnOK">
<Button.Triggers>
<Trigger>
<!-- Update source -->
</Trigger>
</Button.Triggers>
</Button>
Ich dachte über zwei Möglichkeiten:
- Set UpdateSourceMode oder einige andere Sachen in der Bindung.
- ein Eventtrigger fest, die Quelle auf die Schaltfläche klicken aktualisiert.
Mögliche, oder ich habe es mit dem Code zu tun?
Lösung
Sie müssen Code verwenden. Im Einzelnen:
- Stellen Sie
UpdateSourceTrigger=Explicit
auf demTextBox
. - Rufen Sie
UpdateSource
wenn der Benutzer klickt auf dieButton
.
Sie können jedoch den Code im Code hinter oder in einer Verhalten angebracht .
Andere Tipps
Ich weiß, es ist eine Weile her, aber ich kam in der gleichen Ausgabe und möchte, dass meine Lösung teilen. Hoffe, es wird für jemanden hilfreich.
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;
}
Hier ist meine Lösung:
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>
Verhalten Definition (geerbt von TargetedTriggerAction ):
public class TextBoxUpdateSourceAction : TargetedTriggerAction<TextBox>
{
protected override void Invoke(object parameter)
{
BindingExpression be = Target.GetBindingExpression(TextBox.TextProperty);
be.UpdateSource();
}
}
Bitte beachten Sie, dass es wichtig ist, TextBoxUpdateSourceAction zu übergeordneten Container (Stackpanel in Beispielcode) zu befestigen.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow