WPF: сбой DependencyProperty пользовательского элемента управления при использовании нескольких экземпляров элемента управления - PullRequest
1 голос
/ 27 января 2011

Я создал пользовательский элемент управления в WPF, который наследуется от ListBox. В этом я реализовал свое собственное свойство, которое является BindingList. Чтобы сделать это свойство привязываемым, я реализовал его как DependencyProperty:

public BindingList<CheckableListItem> CheckedItems
{
    get
    {
        return (BindingList<CheckableListItem>)GetValue(MultiComboBox.CheckedItemsProperty);
    }
    set
    {
        SetValue(MultiComboBox.CheckedItemsProperty, value);
    }
}
public static readonly DependencyProperty CheckedItemsProperty;

Я регистрирую этот DependencyProperty в статическом конструкторе внутри своего пользовательского элемента управления:

CheckedItemsProperty = DependencyProperty.Register("CheckedItems",
    typeof(BindingList<CheckableListItem>),
    typeof(MultiComboBox),
    new FrameworkPropertyMetadata(new BindingList<CheckableListItem>()));

(MultiComboBox - это имя моего пользовательского элемента управления. CheckableListItem - простой класс, который я написал только для этой цели).

Этот BindingList затем обновляется внутри пользовательского элемента управления (никогда вне), когда пользователь взаимодействует с ним.

Когда я использую свой пользовательский элемент управления в XAML, я связываюсь со свойством CheckItems в режиме «OneWayToSource». Я использую шаблон MVVM, и свойство в ViewModel, к которому я привязываюсь, также является BindingList. ViewModel никогда не влияет на этот список, он просто реагирует на изменения, которые пользовательский элемент управления вносит в список. Свойство в ViewModel выглядит следующим образом:

private BindingList<CheckableListItem> _selectedItems;
public BindingList<CheckableListItem> SelectedItems
{
    get
    {
        return _selectedItems;
    }
    set
    {
        if (value != _selectedItems)
        {
            if (_selectedItems != null)
            {
                _selectedItems.ListChanged -= SelectedItemsChanged;
            }
            _selectedItems = value;
            if (_selectedItems != null)
            {
                _selectedItems.ListChanged += SelectedItemsChanged;
            }
            OnPropertyChanged("SelectedItems");
        }
    }
}

Как вы видите, я слушаю изменения, внесенные в список (эти изменения всегда происходят внутри моего пользовательского элемента управления), и в методе "SelectedItemsChanged" я соответствующим образом обновляю свою модель.

Теперь ... это прекрасно работает, когда у меня есть один из этих элементов управления в моем представлении. Однако, если я помещу два (или более) из них в один и тот же вид, странные вещи начнут происходить. Это, конечно, будет означать, что у меня будет два списка с выбранными элементами в моей ViewModel. Но если вы сделаете что-то в представлении, которое изменит один из списков, это затронет оба списка! То есть обработчики событий для события ListChanged запускаются для обоих списков, если в какой-либо из них внесены изменения!

Кто-нибудь признает эту проблему и / или имеет решение? Что не так с моей реализацией?

Мое первое, хотя это то, что DependencyProperty является статическим. Обычно это означает, что он используется всеми экземплярами. Но я полагаю, что DependencyProperties работают каким-то другим «волшебным» образом, так что это может не быть проблемой.

Любые советы или подсказки приветствуются!

Ответы [ 2 ]

2 голосов
/ 18 марта 2011

У меня была похожая проблема со свойством зависимости типа коллекции.Мое решение было взято из статьи MSDN Свойства зависимости типа коллекции .Он добавлял следующую строку

SetValue(OperatorsPropertyKey, new List<ListBoxItem>()); //replace key and type

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

0 голосов
/ 27 января 2011

Звучит так, как будто вы привязали оба / все виды к одной и той же модели представления. Это объясняет, что изменения одного вызывают изменения в другом.

...