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:
- When I click the button, it's
Content
is not updated with the string"changed"
- 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.