ObservableCollection<T> инициализировать из xaml - Silverlight

У меня есть следующий DependencyProperty в 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 ) {
    ...
}

Я пытаюсь инициализировать его из 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>

Но это не работает! Нет исключений, нет ошибок, но OnColumnsChanged не вызывается.

Любая идея?

1 ответ

Решение

Я полностью смоделировал ваш пример, и в основном вы ожидаете событие изменения свойства для изменений содержимого ObservableCollection. Ваш обработчик событий срабатывает только в случае замены самой коллекции, тогда как вы заменяете только дочерние элементы, а не коллекцию.

Единственный фрагмент вашего кода, который попадет под удар - это получатель:

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

Может быть более изящный способ привязки событий к динамически создаваемым свойствам, но это будет работать:

    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
    }

Это добавление CollectionChanged Хандер к коллекции, а не прислушиваться к самой коллекции, которая будет заменена.

* Вы заметите, что сеттер пытается удалить хандера из любой предыдущей коллекции. Это мера "на всякий случай", так как в противном случае коллекция, отсоединенная от этого свойства, все равно будет сообщать об изменениях после удаления. Это не обязательно, чтобы заставить его работать для начальной коллекции, которую добавляет ваша собственность

Другие вопросы по тегам