Интересно также и то, что WPF должен быть как бы легче в использовании, ведь в Microsoft отделили дизайнеров от программистов, добавили векторную систему визуализации, язык XAML и прочее.
После продолжительного негодования я открыл большую и толстую книгу по WPF. И вот, чудо! Там было всё, как изменить размер, переименовать и перекрасить что угодно и как угодно, но о том, как элементарно достать запись из DataGrid не было и слова.
Отчаявшись, я решил было перейти на WinForm, но вспомнив старую добрую пословицу «если программа не работает, то проблема не в коде, а в программисте», решил разобраться в проблеме и
Привожу пример, как положить и достать информацию из DataGrid в WPF:
Для начала создадим новое приложение и в главном окне разместим элемент DataGrid, назовём его grid.
Далее создадим класс, который будет хранить информацию для таблицы:
class MyTable
{
public MyTable(int Id, string Vocalist, string Album, int Year)
{
this.Id = Id;
this.Vocalist = Vocalist;
this.Album = Album;
this.Year = Year;
}
public int Id { get; set; }
public string Vocalist { get; set; }
public string Album { get; set; }
public int Year { get; set; }
}
После этого заполним таблицу с помощью события Loaded:
//Добавим информацию в таблицу
private void grid_Loaded(object sender, RoutedEventArgs e)
{
List<MyTable> result = new List<MyTable>(3);
result.Add(new MyTable(1, "Майкл Джексон", "Thriller", 1982));
result.Add(new MyTable(2, "AC/DC", "Back in Black", 1980));
result.Add(new MyTable(3, "Bee Gees", "Saturday Night Fever", 1977));
result.Add(new MyTable(4, "Pink Floyd", "The Dark Side of the Moon", 1973));
grid.ItemsSource = result;
}
После всего получим информацию о строчке по событию MouseUp (клик мышкой):
//Получаем данные из таблицы
private void grid_MouseUp(object sender, MouseButtonEventArgs e)
{
MyTable path = grid.SelectedItem as MyTable;
MessageBox.Show(" ID: " + path.Id + "\n Исполнитель: " + path.Vocalist + "\n Альбом: " + path.Album
+ "\n Год: " + path.Year);
}
Заключение
Обратите внимание, что обращаться к элементам таблицы в WPF действительно легче, чем в WinForm (напомню, что в WinForm нужно обязательно указывать номер столбца и ячейки), более того, таблица сохраняет исходный тип данных и это очень удобно при их обработке.
Скриншот того, что получилось:
<Window x:Class="DataGrid.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid x:Name="grid" HorizontalAlignment="Left" Height="251" Margin="23,23,0,0" VerticalAlignment="Top" Width="455" Loaded="grid_Loaded" MouseUp="grid_MouseUp"/>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace DataGrid
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
//Загрузка содержимого таблицы
private void grid_Loaded(object sender, RoutedEventArgs e)
{
List<MyTable> result = new List<MyTable>(3);
result.Add(new MyTable(1, "Майкл Джексон", "Thriller", 1982));
result.Add(new MyTable(2, "AC/DC", "Back in Black", 1980));
result.Add(new MyTable(3, "Bee Gees", "Saturday Night Fever", 1977));
result.Add(new MyTable(4, "Pink Floyd", "The Dark Side of the Moon", 1973));
grid.ItemsSource = result;
}
//Получаем данные из таблицы
private void grid_MouseUp(object sender, MouseButtonEventArgs e)
{
MyTable path = grid.SelectedItem as MyTable;
MessageBox.Show(" ID: " + path.Id + "\n Исполнитель: " + path.Vocalist + "\n Альбом: " + path.Album
+ "\n Год: " + path.Year);
}
}
class MyTable
{
public MyTable(int Id, string Vocalist, string Album, int Year)
{
this.Id = Id;
this.Vocalist = Vocalist;
this.Album = Album;
this.Year = Year;
}
public int Id { get; set; }
public string Vocalist { get; set; }
public string Album { get; set; }
public int Year { get; set; }
}
}
Для примера использован Visual Studio 2012 и .net 4.0.
[ Исходный код проекта ]
Сыслка на источник: www.dotnetperls.com/datagrid
P.S. Не знаю, может, я рассказал очевидную для кого-то вещь, однако на это потратил довольно много времени, поэтому и решил поделиться.
Комментарии (24)
agranom555
08.11.2015 15:40Эммм. В WPF у всех таблиц и списочных элементов есть свойства SelectedItem или SelectedItems.
michael_vostrikov
08.11.2015 15:46+6Как-то быстро у вас заключение появилось, еще даже не началось ничего…
однако на это потратил довольно много времени
На приложение уровня «Hello world»? Вы правда считаете, что стоит всем об этом рассказывать?DimaFromMai
08.11.2015 16:12-3Программка, в которой использовал таблицу здесь: Программа, это музыкальный плеер с использованием WCF. А приложение написал попроще, чтобы не перегружать кодом.
AlekseenkoAV
08.11.2015 20:17+3А если серьезно, то посмотрите WPF + MVVM, это перевернет ваше мировоззрение на построение GUI. Я не являюсь ярым фанатом того, что делает Microsoft, но это блестящая разработка.
DimaFromMai
08.11.2015 21:51-3Сразу надо было написать о том, что статья ни в коем случае не описывает вообще весь WPF, а только показывает прием программирования.
Да, конечно, я согласен с тем, что необходимо посмотреть WPF + MVVM чтобы во всём разобраться и стать профессионалом, но бывает такое, что нужно срочно сдать работу, например лабу или курсовую или ещё что, так вот для таких случаев бысторо разобраться, что к чему было бы лучше всего. Сам лично я не раз попадал в такие ситуации, когда например не зная толком языка программирования нужно было быстро написать рабочее приложение и в таких случаях я использую подобные примеры, а не пытаюсь за ночь выучить до профессионального уровня язык программирования.Seekeer
09.11.2015 08:55+2«например лабу или курсовую или ещё что, так вот для таких случаев бысторо разобраться, что к чему было бы лучше всего. Сам лично я не раз попадал в такие ситуации, когда например не зная толком языка программирования нужно было быстро написать рабочее приложение»
Ну если для вас цель лабораторной работы не в том, чтобы по настоящему чему-то научиться, а чтобы её сдать, то да, такой подход подойдёт.
Да и то — если преподаватель не слишком внимательный.
«взял самый свежий .net framework 4.5» «использован Visual Studio 2012 и .net 4.0.»
Во-первых, вы указываете разные версии фреймворка, во-вторых, 4.5 не самая свежая версия, в третьих — зачем пользоваться 12ой студией?DimaFromMai
09.11.2015 09:49-2На момент написания программы (не этого примера) был самый свежий .net 4.5. Использовал .net 4.0 для большей совместимости, а вдруг кто-то использует windows XP, а Visual Studio 2012 просто был под рукой (более того и 13-ая и 15-ая без проблем откроют проект из 12-ой студии).
Вот не выполните вовремя запрос (например не напишите программу), а с вас возьмут да и стребуют денежный штраф за срыв сроков выполнения работ, будете знать.DimaFromMai
09.11.2015 10:16С windows XP погорячился, там вроде ничего выше VS 2010 не устанавливается.
NeoNN
09.11.2015 10:23+1Навряд ли в мире нормальной разработки с вас потребуют денежный штраф за срыв сроков. Хуже может быть, когда напишете в срок плохую программу, а она на проде не заработает нормально и будет адом в поддержке другими программистами — это в первую очередь скажется на вашей репутации. Если продолжите изучение программирования, .net и WPF, будете со смехом вспоминать эту статью и комментарии к ней.
Daniro_San
09.11.2015 10:33Я как раз использую XP. Спасибо.
Ваша статья, как и ваш пример, несомненно, пролила свет на все скрытые аспекты и подводные камни WPF.
то подобный пример будет предпочтительней прочтения двух-трёх толстых книжек.
Пример великолепен.
Теперь я могу быдлокодить без, как вы правильно сказали, книжек.
Еще раз спасибо за столь содержательную статьюКартинка для вас
http://cs13.imagefiles.me/p/086191075125228012204046149162246194251016097051012226/1447054334/107634773/0/da9aeb6205f2bfe402d88f18c1c88da2/d0e31a50335c5b70ebddbfc5d0cec505/0/Daniro/asdf-spaces.ru.jpg
Sing
09.11.2015 11:03Ещё, постарайтесь именовать классы и методы соответственно и понятно. Особенно, если кому-то показываете. Название должно быть понятным и отражающим суть того, для чего класс или метод нужен.
Например, DimaFromMai даёт немало информации о том, кто это и откуда. А вот MyTable ничего не говорит. Более того, это вообще не таблица, а, судя по коду, даже и не класс, а структура. Пользу структур, кстати, тоже изучите.
HomoLuden
09.11.2015 14:25+1Очень не рекомендую начинать (да и продолжать на самом деле) со стокового DataGrid в WPF. У него очень тежеловесный дизайн (архитектура и графическое дерево). Если Вам не нужны его встроенные фичи, а в реальных случаях велик шанс, что специфичные сценарии не получится с DataGrid реализовать именно так как UX спец написал, то лучше использовать ListView + GridView.
Сортировку и Фильтрацию надежнее снаружи реализовывать. При этом тормозов с ListView намного меньше будет.
Я профилировал перформанс двух одинаковых реализаций части экрана с DataGrid и ListView. Производительность отличается в разы в случае двухуровневых списков (Master и Details).
CrazyViper
09.11.2015 14:31Самое интересное в том, что платформа WPF полностью переработана и многое из того, что работало в WinForm в WPF не работает вообще никак.
Фраза в корне не корректная. WPF — это не переработанный WinForms. Это отдельная платформа, написанная с нуля. Там совершенно другой механизм рендеринга. Да, классы называются похожими словами, реализованы на том же C# с тем же синтаксисом. Но суть совершенно другая. Именно поэтому у вас в статье кроме слова WPF ничего про WPF нет.
Ну и выше вам уже рекомендовали почитать про MVVM.DimaFromMai
09.11.2015 17:50Я и не писал, что WPF — это переработанный WinForm, но спасибо за уточнение.
DataGrid работает только в WPF, в WinForm работать не будет.
Согласен с вами и с теми кто выше, обязательно прочитаю про MVVM.
NeoNN
Хабрамашина времени перенесла нас на 10 лет назад.
NeoNN
А если без шуток, то успехов в изучении. Информацию по классам и подходам к программированию лучше всего искать не в яндексе, а в гугле, на msdn и stackoverflow на английском языке. В рамках WPF очень полезно прочитать про MVVM и IoC Containers, если использовать их сразу, то сберегут кучу времени и нервов.
Сама статья, к сожалению, никакой образовательной ценности не несет.
DimaFromMai
Да так и написал: «Не знаю, может, я рассказал очевидную для кого-то вещь...»
NeoNN
Для тех, для кого она неочевидна, она будет вредна, так как поведет по неправильному пути в изучении WPF.
DimaFromMai
Согласен, но если нужно быстро написать приложение, то подобный пример будет предпочтительней прочтения двух-трёх толстых книжек.
И Яндекс отличный поисковик, не уступающий гуглу (конечно это только моё мнение).
dordzhiev
Все о DataGrid, без «прочтения двух-трех толстых книжек».
DimaFromMai
Вы эту статью читали? Да, там есть информация о том, как поменять размер колонки или как перекрасить строчку, но того о чём написал здесь я, там нет.Действительно, с первого раза не заметил, но кратко свойство SelectedItem упоминается, причём без примера.HomoLuden
Все правильно написали. Поисковик нужен для выдачи решения для конкретной проблемы в как можно более сжатом виде, а не энциклопедической статьи.
HomoLuden
PS: если собираетесь программно или автоматически менять размеры колонок, то сразу отказывайтесь от DataGrid. он больше любит фиксированные размеры колонок, отсутствие адаптивности под размеры экрана и ручной ресайз юзером.
А с авторесайзом и резиновым дизайном сразу убивается производительность старта приложения с DataGrid, т.к. этот контрол на старте делает ресайз несколько раз => UpdateLayout() с DataGrid ужирает процессор по-максимуму.
С ListView протребление значительно ниже.
HomoLuden
«Искать в гугле» не значит, что яндекс — плохой поисковик. Скорее это вопрос специализации. Для девелоперских нужд выдача гугла релевантнее, субъективное ИМХО.