Is there a way to get UpdateSourceTrigger=PropertyChanged for compiled bindings?

I'm working on a UWP application and I realized that the default UpdateSourceTrigger mode for the TextBox control, which is LostFocus, can't be changed when using a compiled binding.

This means that whenever I want the binding to update for a TextBox, I have to use all this repeated boilerplate:

<TextBox
    Text="{x:Bind ViewModel.Title, Mode=TwoWay}"
    TextChanged="TextBox_OnTextChanged"/>
private void TextBox_OnTextChanged(object sender, TextChangedEventArgs e)
{
    ViewModel.Title = ((TextBox)sender).Text;
}

Now, this is not too bad, but having to remember to create the TextChanged handler every single time a TextBox is used is annoying and error prone.

This would work fine with a classic binding:

<TextBox Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

But of course, here there would be the additional overhead of usinc classic bindings (involving runtime reflections, etc.).

Is there a way to get the same behaviour of UpdateSourceTrigger=PropertyChanged as well? I'd be completely fine with, say, writing a custom attached property that sets things up, as long as I can do everything I need directly from XAML, with no code behind involved.

Thanks!

1 answer

  • answered 2019-04-22 06:45 Nico Zhu - MSFT

    Please check UpdateSourceTrigger documentation.

    The default UpdateSourceTrigger value is Default. And using default behavior from the dependency property that uses the binding. In Windows Runtime, this evaluates the same as a value with PropertyChanged. If you used Text="{x:Bind ViewModel.Title, Mode=TwoWay}", the Title will be changed when text changes. we have not need modify the viewmode in TextChanged even handler.

    The premise is that we need implement INotifyPropertyChanged like the follow.

    public class HostViewModel : INotifyPropertyChanged
    {
        private string nextButtonText;
    
        public event PropertyChangedEventHandler PropertyChanged = delegate { };
    
        public HostViewModel()
        {
            this.NextButtonText = "Next";
        }
    
        public string NextButtonText
        {
            get { return this.nextButtonText; }
            set
            {
                this.nextButtonText = value;
                this.OnPropertyChanged();
            }
        }
    
        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            // Raise the PropertyChanged event, passing the name of the property whose value has changed.
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    For more detail please refer Data binding in depth document.