#c# #xaml #gridview #observablecollection
#c# #xaml #просмотр сетки #сбор данных observablecollection
Вопрос:
У меня есть класс, производный от BindableBase, который содержит два свойства:
private string sourceCallNumber;
public string SourceCallNumber
{
get { return sourceCallNumber; }
set { SetProperty(ref sourceCallNumber, value); }
}
private string sourceMediaType;
public string SourceMediaType
{
get { return sourceMediaType; }
set { SetProperty(ref sourceMediaType, value); }
}
У меня есть ObservableCollection, который содержит несколько элементов, использующих этот класс.
У меня есть GridView, для которого я установил ItemsSource так, чтобы он указывал на ObservableCollection.
Моя проблема в том, что если я изменяю значение, скажем, SourceMediaType для одного из элементов, отображение не обновляется. Я включил отладку и могу подтвердить, что изменение значения приводит к запуску OnPropertyChanged для этого свойства.
Я прочитал довольно много вопросов и ответов SO о подобных проблемах, и я совсем запутался в том, что мне нужно сделать, чтобы заставить это работать.
Насколько я понимаю, хотя ObservableCollection сам по себе ничего не делает при изменении свойства, если сам элемент запускает OnPropertyChanged, это должно привести к обновлению отображения.
(Я прочитал один ответ, в котором предлагалось использовать предоставленный код под названием TrulyObservableCollection, но проблема, с которой я столкнулся, заключается в том, что обновляется все, а не только один элемент, который был обновлен).
Что я упускаю или недопонимаю, пожалуйста?
Спасибо.
Комментарии:
1. В том, как вы объяснили, нет ничего плохого. Вы уверены, что привязка не одноразовая? Не могли бы вы также добавить код Xaml?
2. Я сделаю дикий скачок здесь, в вашей функции setProperty, разве вы не должны передавать строку, представляющую фактическое изменяемое свойство? Если вы не получите имя свойства из имени поля (что потребует, чтобы все следовали одному и тому же шаблону).
3. @Reza — нет, привязка не одноразовая.
4. @RodrigoSilva Ты был на правильном пути. setProperty действительно получает имя свойства из имени поля … но это не то, к чему привязывался XAML. XAML был привязан к другому свойству, которое добавляло некоторое форматирование вокруг текста. Явное упоминание этого имени устранило проблему. Мне нужно быть умнее с моим XAML и использовать конвертеры, а не разные свойства.
Ответ №1:
Приложения на C # должны реализовывать INotifyCollectionChanged и System .Коллекции.IList (не IList из T).
public class NameList : ObservableCollection<PersonName>
{
public NameList() : base()
{
Add(new PersonName("Willa", "Cather"));
Add(new PersonName("Isak", "Dinesen"));
Add(new PersonName("Victor", "Hugo"));
Add(new PersonName("Jules", "Verne"));
}
}
public class PersonName
{
private string firstName;
private string lastName;
public PersonName(string first, string last)
{
firstName = first;
lastName = last;
}
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
}
Посмотрите на GridView.
Комментарии:
1. Хотя вы правы в том, что INotifyCollectionChanged необходимо реализовать, ObservableCollection<T> делает это. Ссылка: msdn.microsoft.com/en-US/library/windows/apps/xaml /… (в разделе Привязка элемента управления к коллекции объектов).
Ответ №2:
@RodrigoSilva указал мне правильный путь … XAML, который ссылается на значения, был таким:
<StackPanel>
<TextBlock Text="{Binding DisplayCallNumber}" Style="{StaticResource TitleTextBlockStyle}" Visibility="{Binding GotCallNumber, Converter={StaticResource DisplayIfTrue}}" Margin="0,0,0,10"/>
<TextBlock Text="{Binding DisplayMediaType}" Style="{StaticResource ItemTextStyle}" Visibility="{Binding GotMediaType, Converter={StaticResource DisplayIfTrue}}" Margin="0,0,0,10"/>
</StackPanel>
который напрямую не ссылается на базовые свойства SourceCallNumber и SourceMediaType . В результате, хотя OnPropertyChanged корректно запускается для SourceCallNumber и SourceMediaType , это не приводит к обновлению отображения, потому что это не то, на что указывает XAML.
Явное изменение вызова setProperty на это:
SetProperty(ref sourceCallNumber, value, "DisplayCallNumber");
устраняет проблему, но не является ХОРОШИМ решением, потому что какая-то другая часть приложения может фактически привязываться к SourceCallNumber и не получит обновление свойства после этого изменения. ХОРОШИМ решением является использование конвертера, как описано в http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh464965.aspx .