开发者

ObservableCollection<T> initialize from xaml - Silverlight

开发者 https://www.devze.com 2023-03-19 03:08 出处:网络
I have the following DependencyProperty in a Silverlight UserControl: public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register( \"Columns\", typeof( ObservableCollectio

I have the following DependencyProperty in a Silverlight UserControl:

public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register( "Columns", typeof( ObservableCollection<FilterableDataGridColumn> ), typeof( FilterableDataGridControl ), new PropertyMetadata( new ObservableCollection<FilterableDataGridColumn>(), new PropertyChangedCallback( OnColumnsChanged ) ) );

public ObservableCollection<FilterableDataGridColumn> Columns {
 开发者_开发技巧   get {
        return ( ObservableCollection<FilterableDataGridColumn> )GetValue( ColumnsProperty );
    }
    set {
        SetValue( ColumnsProperty, value );
    }
}

static void OnColumnsChanged( object sender, DependencyPropertyChangedEventArgs args ) {
    ...
}

I'm trying to initialize it from xaml:

<my:FilterableDataGridControl ... >
    <my:FilterableDataGridControl.Columns>
        <my:FilterableDataGridColumn Header="Name" PropertyName="Name" ColumnType="Text" />
        <my:FilterableDataGridColumn Header="Type" PropertyName="Type" ColumnType="Text" />
    </my:FilterableDataGridControl.Columns>
</my:FilterableDataGridControl>

But it doesn't work! No exception, no error, but the OnColumnsChanged is not invoked.

Any idea?


I mocked up your example in full and basically you are expecting a property change event to occur for the content changes of an ObservableCollection. Your event handler is only triggered if the collection itself is replaced, whereas you are replacing child elements only and not the collection.

The only piece of your code that will get hit is the getter:

get { return (ObservableCollection<FilterableDataGridColumn>)GetValue(ColumnsProperty); }

There may be a more graceful way to hookup events to dynamically created properties, but this will work:

    public ObservableCollection<FilterableDataGridColumn> Columns
    {
        get
        {
            var columns = (ObservableCollection<FilterableDataGridColumn>)GetValue(ColumnsProperty);
            columns.CollectionChanged -= columns_CollectionChanged; // Disconnect each time we reconnect
            columns.CollectionChanged += columns_CollectionChanged;
            return columns;
        }
        set
        {
            var columns = (ObservableCollection<FilterableDataGridColumn>)GetValue(ColumnsProperty);
            if (columns != null)
            {
                columns.CollectionChanged -= columns_CollectionChanged; // Disconnect each time we change collection
            }
            SetValue(ColumnsProperty, value);
        }
    }

    void columns_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        // This will get hit
    }

This is adding a CollectionChanged hander to the collection, rather than listening for the collection itself to be replaced.

*You will note the setter goes to the trouble of removing the hander from any previous collection. This is a "just in case" measure as otherwise a collection disconnected from this property would still report changes after removal. This is not required to make it work for the initial collection your property adds

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号