问题
I am rewrite my UWP Application from Binding to x:Bind. I have a TextChanged Event on different Textboxes. With Binding I could use GetBindingExpression to update the Model. Is there an equivalent Methode for x:Bind? Or how could I make it with x:Bind?
public void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var binding = ((TextBox)sender).GetBindingExpression(TextBox.TextProperty);
binding.UpdateSource();
}
回答1:
I've tried to do this before without success. I think is not available for now, because Bind it's just a markup extension. Here is the documentation and examples how to use it https://msdn.microsoft.com/en-us/library/windows/apps/mt204783.aspx
回答2:
The FrameworkElement.GetBindingExpression method returns the BindingExpression that contains information about a single instance of a Binding.
So this can only be used in Binding. According to your posted code, it seems you want use x:Bind to update source when the text changed. In Binding, we can set UpdateSourceTrigger to PropertyChanged
to do this:
<TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="200" Margin="5" />
But there is no UpdateSourceTrigger
property for x:Bind and it only triggers on lost focus. So I suggest you keep using Binding in this case.
回答3:
Compiled Bindings x:Bind
are directives that are executed at design time to generate code to register event handlers and explicitly set the relevant properties, bypassing the {Binding}
registration that uses reflection at runtime, so at runtime there is no way to detect or get a handle to the binding statement from an x:Bind
because there is none.
As partially explained by @Jayden, it is not necessary to obtain the binding at all in your specific case, as it is not necessary to manually/explicity call update on the binding when the text is changed, to do so is counter intuitive and leads to unexpected results.
The correct way to ensure that immediate changes to the Text
property of a TextBox
are comitted back through a traditional TwoWay {Binding}
or a compiled TwoWay {x:Bind}
is by setting the UpdateSourceTrigger=PropertyChanged
.
in UWP, both
{Binding}
and{X:Bind}
support UpdatteSourceTrigger, however{X:Bind}
has a simpler implentation with limited options, however both do supportPropertyChanged
Both of the following would work:
<TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Width="200"
Margin="5" />
<TextBox Text="{x:Bind VM.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Width="200"
Margin="5" />
The ONLY time that you would manually update the binding is if your binding statement has set the UpdateSourceTrigger
to Explicit
.
The reason that you should not try to manually update binding is because it will conflict with the binding statement, especially if the binding is deliberately set to
UpdateSourceTrigger=LostFocus
. In this case your event handler will still update the binding on text change, when or if this becomes a problem for developers in the future they will not think to look for explicit handling of the text changed event
As part of a migration to compiled bindings x:Bind
and acknowledging that they could be used for any bindings, you should carefully review all calls to GetBindingExpression()
in your code and try to elminate them as GetBindingExpression()
is no longer a reliable mechanism to determine if a DependencyProperty
has been configured, or to get the binding statement for a DependencyProperty
at runtime.
I am aware of one standard control (NumberBox
) that does not properly support UpdateSourceTrigger=PropertyChanged
, however due to the fact that you cannot determine if a compiled binding has been used to bind a property other solutions need to be used to affect the changes that we are expecting, see this post for solutions to NumberBox
来源:https://stackoverflow.com/questions/35726792/uwp-using-getbindingexpression-with-xbind