DataGrid не обновляется с помощью ObservableCollection

#c# #wpf #datagrid

#c# #wpf #datagrid

Вопрос:

Я реализовал a DataGrid следующим образом:

 <DataGrid Name="grdSignals" Grid.Column="1" ItemsSource="{Binding}"  AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Signal Name" Binding="{Binding SignalName}"/>
        <DataGridTextColumn Header="Value" Binding="{Binding SignalValue}" />
    </DataGrid.Columns>
</DataGrid>
  

Ниже Class я реализовал свойства, используемые в ObservableCollection :

 namespace Test
{
    public partial class MyMain : UserControl
    {        
        public ObservableCollection<Signals> ocSignalNames;
        Signals time, mode;

        public MyMain()
        {
            InitializeComponent();    
            ocSignalNames = new ObservableCollection<Signals>();            
            time = new Signals() { SignalName = "Time", SignalValue = "" };
            mode = new Signals() { SignalName = "Mode", SignalValue = "" };
            ocSignalNames.Add(time);
            ocSignalNames.Add(mode);
            grdSignals.DataContext = ocSignalNames;
        }
    }

    public class Signals : INotifyPropertyChanged
    {
        string _signalName, _signalValue;
        public string SignalName
        {
            get
            {
                return _signalName;
            }
            set
            {
                _signalName = value;
            }
        }

        public string SignalValue
        {
            get
            {
                return _signalValue;
            }
            set
            {
                _signalValue = value;
                OnPropertyChanged(SignalValue);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
  

После его отладки я обнаружил, что ocSignalNames он обновляется при изменении его элементов. Но изменения не отражаются в DataGrid . Я обновляю элементы в потоке следующим образом:

 time.SignalValue = iTest1.ToString();
mode.SignalValue = iTest2.ToString();
  

Что я упускаю?

Комментарии:

1. Наблюдаемая коллекция уведомляет только об изменениях в коллекции, а не об изменениях в элементах внутри коллекции.

2. Это поток UIThread или NonUIThread ?

3. Вызов диспетчера из NonUIThread для обновления значений в пользовательском интерфейсе.

Ответ №1:

Вам не хватает правильных обработчиков NotifyChanged:

     public string SignalName
    {
        get
        {
            return _signalName;
        }
        set
        {
            _signalName = value;
            OnPropertyChanged("SignalName"); //Added
        }
    }

    public string SignalValue
    {
        get
        {
            return _signalValue;
        }
        set
        {
            _signalValue = value;
            OnPropertyChanged("SignalValue"); //NOTE: quotation marks added
        }
    }
  

Комментарии:

1. Ну, мне не нужно SignalName обновлять свойство. Только SignalValue . Его обновление в ObservableCollection .

2. В вашем коде отсутствуют кавычки: OnPropertyChanged(SignalValue) vs OnPropertyChanged("SignalValue") .

3. Он обновляется в ObservableCollection. Здесь это не имеет значения … уведомление о PropertyChanged событии изменений обновит пользовательский интерфейс, и вы, похоже, не делаете этого в настоящее время.

4. Хорошо, я понял! Не думал, что это будет проблемой. Я, вероятно, не стал бы задавать здесь вопрос, если бы свойство не было строкового типа. Спасибо за быстрый ответ, ребята.

Ответ №2:

вы должны использовать приведенный ниже код.

  string _signalName, _signalValue;
    public string SignalName
    {
        get
        {
            return _signalName;
        }
        set
        {
            _signalName = value;
            OnPropertyChanged("SignalName");
        }
    }

    public string SignalValue
    {
        get
        {
            return _signalValue;
        }
        set
        {
            _signalValue = value;
            OnPropertyChanged(SignalValue);
        }
    }
  

ваш XAML выглядит так

  <DataGrid Name="grdSignals" Grid.Column="1" ItemsSource="{Binding}"  AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Signal Name" Binding="{Binding SignalName, Mode=TwoWay}"/>
            <DataGridTextColumn Header="Value" Binding="{Binding SignalValue, Mode=TwoWay}" />
        </DataGrid.Columns>
    </DataGrid>
  

O/P

введите описание изображения здесь

Комментарии:

1. чем здесь отличается ответ, который я опубликовал?

2. OP прокомментировал, что он не работает, поэтому я показал ему полный путь в моем ans с выводом