Home > Net >  Button's SourceUpdated handler not being triggered, and changes to bound source not reflected i
Button's SourceUpdated handler not being triggered, and changes to bound source not reflected i

Time:10-29

I am experimenting with the NotifyOnSourceUpdated property in the following minimal WPF app:

XAML file:

<Window x:Class="notify_on_source_updated.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:notify_on_source_updated"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Button x:Name="myButton" Click="myButton_Click" />
</Window>

Code-behind:

namespace notify_on_source_updated
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public string SourceText {get; set;}
        
        public MainWindow()
        {
            InitializeComponent();
            SourceText = "test";
            Binding binding = new Binding();

            binding.Source = SourceText;
            binding.NotifyOnSourceUpdated=true;
            
            myButton.SourceUpdated  = myButton_SourceUpdated;
            myButton.SetBinding(ContentControl.ContentProperty, binding);
        }

        private void myButton_Click(object sender, RoutedEventArgs e)
        {
            SourceText = "changed";
        }

        private void myButton_SourceUpdated(object sender, DataTransferEventArgs e)
        {
            MessageBox.Show("Updated!");
        }
    }
}

There are two things I'm confused about here:

  1. When I click the button, it's Content is not updated with the string "changed"
  2. The handler I'm attaching to the myButton.SourceUpdated event is not being triggered and I never get the message box.

Why is it that the two above behaviors are not occurring? What am I missing here?

CodePudding user response:

You need to specify a binding path:

public MainWindow()
{
    InitializeComponent();
    SourceText = "test";
    Binding binding = new Binding();

    binding.Path = new PropertyPath(nameof(SourceText));
    binding.Source = this;
    binding.NotifyOnSourceUpdated=true;

    // intList is the ListBox
    myButton.SourceUpdated  = myButton_SourceUpdated;
    myButton.SetBinding(ContentControl.ContentProperty, binding);
}

Then for the Button to update, you need to implement the INotifyPropertyChanged interface and raise the PropertyChanged event for the data-bound source property:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private string _sourceText;
    public string SourceText
    {
        get { return _sourceText; }
        set 
        { 
            _sourceText = value; 
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SourceText))); 
        }
    }

    public event PropertyChangedEventHandler? PropertyChanged;
    ...
}

The other option would to be explicitly update the binding:

private void myButton_Click(object sender, RoutedEventArgs e)
{
    SourceText = "changed";
    myButton.GetBindingExpression(ContentControl.ContentProperty).UpdateTarget();
}

And the SourceUpdated event occurs when a value of an input control is transferred from the binding target to the binding source, for example when you type something into a data-bound TextBox. It's not raised in your example.

  • Related