Текстовое связывание Свойство UserControl для ObservableCollection не обновляется - PullRequest
1 голос
/ 25 августа 2011

Я создал UserControl, который должен отображать преобразованное строковое значение на основе содержимого связанной ObservableCollection.Все работает, когда приложение загружается;Мой IValueConverter вызывается и выдает правильный строковый результат, который корректно отображается в моем UserControl.Однако, если содержимое ObservableCollection изменяется, мой элемент управления не обновляется.

Кроме того, до того, как я создал этот элемент управления, у меня было такое же поведение, но оно связывало свойство Content обычного элемента управления Button, и это также работало правильно и обновлялось, как и ожидалось.

Есть идеи, что мне не хватает, чтобы получить то же самое с моим UserControl?

Свойство control выглядит так:

public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(MyUserControl));

public string Text
{
    get { return GetValue(TextProperty) as string; }
    set { SetValue(TextProperty, value);
}

Соответствующий раздел в XAML UserControl (который отображаетпреобразованное строковое значение) равно;

<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Controls:MyUserControl}}, Path=Text}" />

И элемент управления создается в отдельном окне следующим образом:

<CoreControls:MyUserControl 
    Name="myControl" 
    Text="{Binding Path=ObservableCollectionInstance, Converter={StaticResource MyValueConverter}, Mode=OneWay}" />

Ответы [ 3 ]

1 голос
/ 25 августа 2011

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

1 голос
/ 25 августа 2011

Я бы использовал ElementName вместо RelativeSource в вашей привязке, так как вы назвали свой пользовательский элемент управления.Кроме того, вы пытаетесь связать коллекцию с <Textbox>.<Textbox> предназначен для отображения одного элемента.Вероятно, поэтому он не работает.ObservableCollection запускает CollectionChanged событий, а не PropertyChanged.Даже если он ответит, у вас все равно будут проблемы, потому что ObservableCollection не уведомляет, когда элемент, содержащийся в нем, изменяет свойства - только когда элементы добавляются / удаляются и т. Д. (Думаю, что сама коллекция изменяется).Если вы хотите именно такое поведение, вам придется написать некоторый код.

EDIT после ваших комментариев он звучит так, как будто вы устанавливаете его в режим привязки OneWay, он действует как режим привязки OneTime.
Я бы попробовал это, чтобы помочь вам отладить его:

добавить это xmlns:

xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"

и затем, в вашей привязке, добавьте:

diagnostics:PresentationTraceSources.TraceLevel=High

вот статья об отладке привязок .

другое, что вы можете сделать, это установить точки останова в вашем конвертере.Посмотрите, действительно ли оно обновляется, когда вы добавляете / удаляете вещи в свою коллекцию.Я хотел бы поспорить, что его bc ObservableCollection НЕ запускает события PropertyChanged и что первоначальное обновление происходит, потому что оно не основано на событии обновления.

0 голосов
/ 26 августа 2011

Спасибо за советы, ребята.

Мне удалось найти решение;Я могу обработать событие CollectionChanged на ObservableCollection и затем явно обновить цель с помощью чего-то вроде:

BindingExpression exp = myControl.GetBindingExpression(MyUserControl.TextProperty);
if (null != exp) exp.UpdateTarget();

Как отмечалось, скорее всего, привязка к свойству Text только прослушивает PropertyChangedсобытия, а не NotifyCollectionChanged события, но это решение делает свое дело.

...