Есть 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
поменяется само.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
У меня есть форма с кнопками "вперед" и "назад" условноПри нажатии на кнопку вперед, показываются следующие 5 элементов коллекции...
хочу сделать анимацию заднего фона в простой 2D игре, чтобы при нажатии на клавиши движения, вслед за персонажем начинал в нужную сторону двигаться...
Начал заниматься разработкой игр на UnityПри создании стали возникать проблемы с "чистотой" и "грамотностью" скриптов
Нужна помощь коллективного разума на тему: как залить часть произвольной замкнутой геометрической фигуры?