Search code examples
c#wpfdata-bindingobservablecollectiondependency-properties

collection dependency properties


I have a custom control that has a DependencyProperty of type ObservableCollection that is bound to an observableCollection:

<MyControl MyCollectionProperty = {Binding MyObservableCollection} ...

Problem is adding to MyObservableCollection does not update MyCollectionProperty.

I need to completly replace the MyObservableCollection to make it work e.g.

MyObservableCollection = null;
MyObservableCollection = new ObservableCollection(){...}

Is there a better way to deal with this?

EDIT:

    public ObservableCollection<string> Columns
    {
        get { return (ObservableCollection<string>)GetValue(ColumnsProperty); }
        set { SetValue(ColumnsProperty, value); }
    }

    public static readonly DependencyProperty ColumnsProperty =
        DependencyProperty.Register("Columns", typeof(ObservableCollection<string>), typeof(MyControl),
                                    new PropertyMetadata(new ObservableCollection<string>(), OnChanged));

Solution

  • Below is a working example that may help.

    In this example, the method OnChanged is called immediately, when the Add button is clicked "Changed" is written to the console.

    The Control

    public class MyControl : Control
    {
    
        public ObservableCollection<string> ExtraColumns
        {
            get { return (ObservableCollection<string>)GetValue(ExtraColumnsProperty); }
            set { SetValue(ExtraColumnsProperty, value); }
        }
    
        public static readonly DependencyProperty ExtraColumnsProperty =
            DependencyProperty.Register("ExtraColumns", typeof(ObservableCollection<string>), typeof(MyControl),
                                        new PropertyMetadata(new ObservableCollection<string>(), OnChanged));
    
        static void OnChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as MyControl).OnChanged();
    
        }
    
        void OnChanged()
        {
            if ( ExtraColumns != null )
                ExtraColumns.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(ExtraColumns_CollectionChanged);
        }
    
        void ExtraColumns_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            Console.WriteLine("Changed");    
        }
    }
    

    The Window

    <Window x:Class="WpfApplication18.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication18"
        Title="MainWindow" Height="350" Width="525">
      <StackPanel>
        <local:MyControl ExtraColumns="{Binding Extras}"/>
        <Button Click="Button_Click">Add</Button>
      </StackPanel>
    </Window>
    

    Window Code Behind

    public partial class MainWindow : Window
    {
        private ObservableCollection<string> _extras = new ObservableCollection<string>( );
        public ObservableCollection<string> Extras
        {
            get { return _extras; }
            set
            {
                if (value != _extras)
                {
                    _extras = value;
                }
            }
        }
    
    
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Extras.Add("Additional");
        }
    }