WPF binding fails with custom add and remove accessors for INotifyPropertyChanged.PropertyChanged

Posted by emddudley on Stack Overflow See other posts from Stack Overflow or by emddudley
Published on 2010-06-01T17:48:56Z Indexed on 2010/06/01 17:53 UTC
Read the original article Hit count: 455

I have a scenario which is causing strange behavior with WPF data binding and INotifyPropertyChanged. I want a private member of the data binding source to handle the INotifyPropertyChanged.PropertyChanged event.

I get some exceptions which haven't helped me debug, even when I have "Enable .NET Framework source stepping" checked in Visual Studio's options:

A first chance exception of type 'System.ArgumentException' occurred in mscorlib.dll
A first chance exception of type 'System.ArgumentException' occurred in mscorlib.dll
A first chance exception of type 'System.InvalidOperationException' occurred in PresentationCore.dll

Here's the source code:

XAML

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="TestApplication.MainWindow"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    Height="100" Width="100">
    <StackPanel>
        <CheckBox IsChecked="{Binding Path=CheckboxIsChecked}" Content="A" />
        <CheckBox IsChecked="{Binding Path=CheckboxIsChecked}" Content="B" />
    </StackPanel>
</Window>

Normal implementation works

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public bool CheckboxIsChecked
    {
        get { return this.mCheckboxIsChecked; }
        set
        {
            this.mCheckboxIsChecked = value;
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs("CheckboxIsChecked"));
        }
    }

    private bool mCheckboxIsChecked = false;

    public MainWindow() { InitializeComponent(); }
}

Desired implementation doesn't work

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged
    {
        add { lock (this.mHandler) { this.mHandler.PropertyChanged += value; } }
        remove { lock (this.mHandler) { this.mHandler.PropertyChanged -= value; } }
    }

    public bool CheckboxIsChecked
    {
        get { return this.mHandler.CheckboxIsChecked; }
        set { this.mHandler.CheckboxIsChecked = value; }
    }

    private HandlesPropertyChangeEvents mHandler = new HandlesPropertyChangeEvents();

    public MainWindow() { InitializeComponent(); }

    public class HandlesPropertyChangeEvents : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public bool CheckboxIsChecked
        {
            get { return this.mCheckboxIsChecked; }
            set
            {
                this.mCheckboxIsChecked = value;
                PropertyChangedEventHandler handler = this.PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs("CheckboxIsChecked"));
            }
        }

        private bool mCheckboxIsChecked = false;
    }
}

© Stack Overflow or respective owner

Related posts about c#

Related posts about wpf