Значение из строки n, столбца m DataGrid записать в переменную

193
17 апреля 2022, 17:10

Есть 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();
Answer 1

Нашел способ. Дело в том, что в DataGrid за представление ячейки отвечает контрол соответствующего типа. Например для DataGridTextColumn это TextBlock.

А получить его значение можно таким образом:

TextBlock x = dataGrid.Columns[2].GetCellContent(dataGrid.Items[1]) as TextBlock;
string s = x?.Text;

Но еще раз замечу, что так в WPF никто не делает.

А делают немного иначе, объясню на простом примере. Покажу без MVVM, просто с биндингами.

Часть 1. Привязка данных

  1. Создать класс данных (у вас наверное такой есть)
public class MyData
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
  1. Задать DataContext для окна. Если вы не используете MVVM, то проще всего это сделать в конструкторе окна. Это позволит легко и просто пользоваться биндингами в xaml
public MainWindow()
{
    InitializeComponent();
    DataContext = this;
}
  1. Создать коллекцию. Если хочется, чтобы DataGrid сама обновлялась, когда в коллекцию добавляются элементы, или удаляются из нее, то лучше использовать ObservableCollection.
public ObservableCollection<MyData> MyCollection { get; set; }

Можно внести в нее какие-нибудь тестовые данные. Работать с коллекцией можно точно так же как с List.

MyCollection = new ObservableCollection<MyData>
{
    new MyData{FirstName="Василий", LastName="Пупкин"},
    new MyData{FirstName="Иван", LastName="Иванов"}
};
  1. И прибиндиться к этой коллекции в xaml
<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;

Часть 2. Двухстороннее обновление данных

Есть такой интерфейс 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 поменяется само.

READ ALSO
Как &quot;сдвинуть&quot; коллекцию от n до m элементов?

Как "сдвинуть" коллекцию от n до m элементов?

У меня есть форма с кнопками "вперед" и "назад" условноПри нажатии на кнопку вперед, показываются следующие 5 элементов коллекции...

210
бесконечная 2D анимация заднего фона (C# unity)

бесконечная 2D анимация заднего фона (C# unity)

хочу сделать анимацию заднего фона в простой 2D игре, чтобы при нажатии на клавиши движения, вслед за персонажем начинал в нужную сторону двигаться...

164
Архитектура приложения(игры) на Unity

Архитектура приложения(игры) на Unity

Начал заниматься разработкой игр на UnityПри создании стали возникать проблемы с "чистотой" и "грамотностью" скриптов

190
Залить часть геометрической фигуры

Залить часть геометрической фигуры

Нужна помощь коллективного разума на тему: как залить часть произвольной замкнутой геометрической фигуры?

157