PropertyChanged для базового класса без INotifyPropertyChanged - PullRequest
0 голосов
/ 02 октября 2018

Простой вопрос, но борьба с решением ...

У меня есть базовый класс.Невозможно реализовать INotifyPropertyChanged в этом базовом классе.

Я использую MVVM (призму), и моя виртуальная машина содержит ObservableCollection.Эта ObservableCollection является itemsSource для Datagrid.

Вопрос: когда я изменяю ячейку в Datagrid, как я могу уведомить свою ВМ, что (и какое) свойство изменилось?

Спасибо!

Редактировать: добавлен код

Базовый класс:

public class BaseClass
{
   public string Name { get; set; }
}

Свойство VM:

private ObservableCollection<BaseClass> mycollection

public ObservableCollection<BaseClass> MyCollection
{
   get
   {
      return mycollection
   }
   set
   {
      SetProperty(ref mycollection, value);
   }
}

XAML:

<DataGrid          
   AutoGenerateColumns="False"
   CanUserAddRows="False"
   GridLinesVisibility="None"
   ItemsSource="{Binding MyCollection, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"                      
   SelectionMode="Single">
   <DataGrid.Columns>
      <DataGridTemplateColumn Width="*" Header="Value">
         <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
               <TextBox Text="{Binding Value,  Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
            </DataTemplate>
         </DataGridTemplateColumn.CellTemplate>
      </DataGridTemplateColumn>  
   </DataGrid.Columns>                  
</DataGrid>

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Предполагая, что <TextBox Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> является опечаткой, и вы имеете в виду Binding Name, и подробно остановитесь на моем комментарии выше:

Если вы хотите уведомить сетку данных (то есть текстовое поле ячейки) об измененииДля Name элемента в вашей коллекции вы должны внедрить INotifyPropertyChanged (если вы не внесете изменения для всей коллекции, что не понравится вашим пользователям, потому что это будет - по крайней мере -сбросить прокрутку).

Если вы хотите уведомить остальную часть своего приложения, когда ваш пользователь изменяет Name элемента, нажав на его ячейку и набрав что-то, вы совершенно свободны в выборе сообщениймеханизм.Конечно, модификация BaseClass.Name предпочтительнее с такими опциями, как

  • INotifyPropertyChanged (может использоваться сервисами, но не ограничивается пользовательским интерфейсом)
  • классический .netсобытие, например, event Action<object,NameChangedEventArgs NameChanged`
  • IEventAggregator, например, _eventAggregator.GetEvent<NameChangedEvent>().Publish( new NameChangedEventArgs( this, newName, oldName ) )

Если вы абсолютно не можете изменить BaseClass, вы можете создать наблюдателя, который будет сидеть ипериодически проверяет все известные ему элементы и сравнивает их текущие имена с последним известным состоянием, а затем выполняет одно из указанных выше действий в случае обнаружения изменений.Однако это не самое эффективное решение, потому что вы должны зарегистрировать все свои элементы и либо отменить их регистрацию, либо использовать слабые ссылки (которые увеличивают накладные расходы).

0 голосов
/ 02 октября 2018

Создайте «фасад», например, создайте модель, которая имеет идентичные свойства, но также наследует от INPC.При изменении свойства «Имя» на фасаде установите значение для объекта «базовый класс», а также вызовите INPC.

public class BaseClass { public string Name { get; set; } }

public class FacadeBaseClasse : INotifyPropertyChanged //Facade that implements INPC interface
{
    private readonly BaseClass baseC;
    public string Name
    {
        get => baseC.Name;
        set 
        {
            baseC.Name = value;
            OnPropertyChange();
        }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...