WP7 LonglistSelector - привязка данных - как вызвать обновление привязки связанного элемента

Элемент управления longlistselector, по-видимому, как раз то, что мне нужно для моего приложения, поскольку у меня есть очень длинный список, который мне нужно отобразить, и мне нравятся реализуемые им функции группировки, но я действительно борюсь с аспектом привязки данных при работе с ним. Потребовалось время, чтобы заставить работать базовую привязку данных, но у меня она полностью функциональна. Если элемент удален или добавлен, пользовательский интерфейс обновляется должным образом, потому что источник данных является производным от ObservableCollection.

Проблема, с которой я сталкиваюсь, состоит в том, что у меня есть флаг в отдельных элементах данных, к которым я привязываю, который указывает, должен ли отдельный элемент списка отображать или скрывать графику. Идея состоит в том, что когда пользователь выполняет жест удержания на элементе, он включает или выключает графику на основе изменений свойств связанного элемента.

    Visibility="{Binding Converter={StaticResource isFavoriteToVisibility}}

Требования к привязке данных LongListSelector для получения заголовков группы и т.п. требуют источника данных, такого как ObservableCollection<ObservableCollection<MyItem>> (что просто сбивает с толку!). По сути, внешняя коллекция - это Группы, а внутренняя коллекция содержит отображаемые элементы. Мои элементы даже реализуют интерфейс INotifyPropertyChanged. Я ожидал, что обновления свойств моего элемента будут автоматически отражаться в моей привязке данных, а не только добавление или удаление элементов из коллекции.

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

Что мне нужно, так это помочь выяснить, что я могу сделать, чтобы вызвать обновление отдельного элемента списка после того, как я изменил свойство его связанного объекта?

Обновить:

Клаус, код, который вы создали, был ОЧЕНЬ полезен (извините, у меня еще недостаточно представителей, чтобы голосовать за вас!) Используя этот код, я смог значительно упростить свой код и сделать больше тестов, но он все еще не делает решить мою проблему.

То, что я сейчас решил, это то, что моя привязка в порядке. Если я изменю свойство при привязке просто к текстовому полю text="{Binding IsFavorite}" он обновляется без нареканий. Кажется, что не работает, когда я обновляю то же свойство при привязке к IValueConverter Visibility="{Binding Converter={StaticResource isFavoriteToVisibility}}" это не обновляет. Конвертер работает нормально при начальном связывании, но не при изменении свойства. Чтобы продолжить тестирование, я связал одно и то же свойство bool как с текстовым полем, так и с IValueConverter. Когда я изменяю значение bool, текстовое поле обновляется, но не поле, связанное с помощью конвертера.

public class VisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Chemical chem = value as Chemical;

        if (chem == null)
            return Visibility.Collapsed;

        if (chem.IsFavorite)
            return Visibility.Visible;
        else
            return Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

XAML:

<myNS:ChemicalToFavoriteVisibilityConverter x:Key="isFavoriteToVisibility" />

<Rectangle Grid.Column="0" 
           Fill="{StaticResource PhoneContrastBackgroundBrush}" 
           Height="26" Stroke="Black"  Width="26" 
           Visibility="{Binding Converter={StaticResource isFavoriteToVisibility}}">
    <Rectangle.OpacityMask>
        <ImageBrush ImageSource="/Images/star_big.png"/>
    </Rectangle.OpacityMask>
</Rectangle>
<StackPanel Grid.Column="1"  Margin="0,0,0,0">
    <TextBlock Text="{Binding IsFavorite}" 
               TextWrapping="Wrap" 
               Style="{StaticResource PhoneTextLargeStyle}" 
               Foreground="{StaticResource PhoneForegroundBrush}"/>
</StackPanel>

2 ответа

Решение

Я решил проблему. Проблема заключалась в том, что я передавал весь объект в IValueConverter вместо конкретного свойства, которое изменилось внутри объекта. Я изменил конвертер, чтобы специально обрабатывать конвертацию bool в Visibility и исправил привязку:

public class BoolToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool boolValue = (bool)value;

        return boolValue ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Привязка изменилась с:
Visibility="{Binding Converter={StaticResource isFavoriteToVisibility}}"

чтобы:
Visibility="{Binding Converter={StaticResource isFavoriteToVisibility}, Path=IsFavorite}"

Можете ли вы проверить, что в привязке вы не используете OneTime в качестве режима привязки (вместо OneWay)?

Я без проблем использовал привязку данных в элементах списка, привязанного к LongListSelector - я подозреваю, что проблема не в LongListSelector, а в вашей привязке или в INotifyPropertyChanged ... вы можете опубликовать некоторый код (в идеале привязку а также связанные объекты).

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