Просмотр сетки XAML, сбор наблюдаемых и изменение свойств элемента

#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 .