#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)
vsOnPropertyChanged("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 с выводом