Есть DataGrid, в одном из столбцов всегда хранится одно и то же числовое значение. Как это самое значение записать в переменную типа int?
Знаю, что в WinForms с DataGridView делается так:
String s = dataGridView1[1, 2].Value.ToString();
А как это делается в WPF c DataGrid - не знаю.
DataGrid:
<DataGrid x:Name="AbitSpecDG" x:FieldModifier="public" AutoGenerateColumns="False" Height="600" Width="1150" IsReadOnly="True"
ScrollViewer.CanContentScroll="True" Background="{x:Null}" LoadingRow="AbitSpecDG_LoadingRow" HeadersVisibility="All">
<DataGrid.Columns>
<DataGridTextColumn Width="auto" Header="ID Абитуриента" Binding="{Binding id_abit}"/>
<DataGridTextColumn Width="auto" Header="ID Специальности" Binding="{Binding id_spec}"/>
<DataGridTextColumn Width="auto" Header="Фамилия" Binding="{Binding abit.MName}"/>
<DataGridTextColumn Width="auto" Header="Имя" Binding="{Binding abit.Name}"/>
<DataGridTextColumn Width="auto" Header="Отчество" Binding="{Binding abit.LName}"/>
<DataGridTextColumn Width="auto" Header="Ср. балл" Binding="{Binding abit.AvgMark}"/>
<DataGridTextColumn Width="auto" Header="Специальность" Binding="{Binding specialty.Name}"/>
<DataGridTextColumn Width="auto" Header="Кол-во мест" Binding="{Binding specialty.NumberOfSeats}"/>
</DataGrid.Columns>
</DataGrid>
Заполнение DataGrid:
abit_spec newAbSpec = new abit_spec()
{
id_abit = Convert.ToInt32(tb_IDabit.Text),
id_spec = Convert.ToInt32(tb_IDspec.Text),
};
db.abit_spec.Add(newAbSpec);
db.SaveChanges();
AbSpec.dataGrid.ItemsSource = db.abit_spec.ToList();
Нашел способ. Дело в том, что в DataGrid за представление ячейки отвечает контрол соответствующего типа. Например для DataGridTextColumn это TextBlock.
А получить его значение можно таким образом:
TextBlock x = dataGrid.Columns[2].GetCellContent(dataGrid.Items[1]) as TextBlock;
string s = x?.Text;
Но еще раз замечу, что так в WPF никто не делает.
А делают немного иначе, объясню на простом примере. Покажу без MVVM, просто с биндингами.
public class MyData
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
DataContext для окна. Если вы не используете MVVM, то проще всего это сделать в конструкторе окна. Это позволит легко и просто пользоваться биндингами в xamlpublic MainWindow()
{
InitializeComponent();
DataContext = this;
}
DataGrid сама обновлялась, когда в коллекцию добавляются элементы, или удаляются из нее, то лучше использовать ObservableCollection.public ObservableCollection<MyData> MyCollection { get; set; }
Можно внести в нее какие-нибудь тестовые данные. Работать с коллекцией можно точно так же как с List.
MyCollection = new ObservableCollection<MyData>
{
new MyData{FirstName="Василий", LastName="Пупкин"},
new MyData{FirstName="Иван", LastName="Иванов"}
};
<DataGrid ItemsSource="{Binding MyCollection}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding FirstName}" Header="Имя"/>
<DataGridTextColumn Binding="{Binding LastName}" Header="Фамилия"/>
</DataGrid.Columns>
</DataGrid>
Чтобы получить элемент коллекции, расположенный во второй колонке и второй строке, можно просто обратиться к данным, так как DataGrid будет обновлять данные автоматически.
string s = MyCollection[1].LastName;
Есть такой интерфейс INotifyPropertyChanged, практически все контролы в WPF поддерживают событие PropertyChanged, если вызвать которое при использовании Binding, то контрол сам себя обновит при обновлении данных.
Вот вам класс помощник, унаследовав который можно сделать так, чтобы когда вы обновляете данные, ячейки таблицы обновлялись сами, а наоборот это уже происходит в результате действий из первой части.
Просто добавьте этот класс отдельно в решение (не внутрь класса Window).
public class NotifyPropertyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Теперь просто остается унаследовать этот класс и модифицировать свойства класса данных следующим образом.
public class MyData : NotifyPropertyChanged
{
private string _firstName;
private string _lastName;
public string FirstName
{
get => _firstName;
set
{
_firstName = value;
OnPropertyChanged(); // сообщить всем биндингам, которые привязаны сюда о том, что данные поменялись
}
}
public string LastName
{
get => _lastName;
set
{
_lastName = value;
OnPropertyChanged();
}
}
}
А теперь становится доступен следующий трюк:
MyCollection[1].LastName = "Петров";
В результате выполнения этого кода, содержимое ячейки в DataGrid поменяется само.
Продвижение своими сайтами как стратегия роста и независимости