Как очистить datagrid c wpf
Как корректно очистить только содержимое столбца DataGrid и удалить все строки, но чтобы хедеры остались, и при добавлении в таблицу опять появлялись строки?
Спросил kiborg
764 дн., 9 час., 55 мин. назад
Новые ответы
Если есть привязка DataGridView к источнику данных, то нужно очистить источник данных. Например, удалить все строки из таблицы или все элементы из списка. Также можно попробовать установить источник данных в null :
dataGridView.DataSource = null;
Если строки добавлялись в gridView вручную, то удалять их тоже нужно вручную, как-то так:
dataGridView.Rows.Clear();
wpf datagrid очистить
теперь мне нужно очистить DataGrid dgrid.Items.Clear(); получаю System.InvalidOperationException: «Операция недопустима, когда ItemsSource используется. Вместо этого получите доступ и измените элементы с помощью ItemsControl.ItemsSource.» как очистить DataGrid ?
Отслеживать
задан 2 фев 2020 в 15:10
920 7 7 серебряных знаков 26 26 бронзовых знаков
Когда вы пишете dgrid.Items.Add(. ) (или как там у него правильно), то в таком варианте коллекцией данных будет являться сам контрол, тогда вы можете уже сделать dgrid.Items.Clear() , что приведет к очистке его данных. Когда вы делаете dgrid.ItemsSource = ds.Tables[0].DefaultView; , то контрол лишь отображает данные из заданной коллекции, не более. То есть в таком случае у вас источником данных является ds.Tables[0].DefaultView , которую вам и надо очищать. Ну или делайте костыли, обнуляйте ItemsSource . Вообще, советую использовать привязки, ибо текущий ваш подход ужасен.
2 фев 2020 в 15:14
Вы назначаете ItemsSource, для очистки тоже работайте с ним, т.е. dataGrid.ItemsSource = null; Так же из MSDN: Если задано свойство ItemsSource, Items коллекция становится доступна только для чтения и имеет фиксированный размер. Если ItemsSource используется, установка свойства ItemsSource в значение null удаляет коллекцию и восстанавливает использование Items
очистка datagrid
DataGrid: установить фокус на строку DataGrid, а не на сам DataGrid
Добрый день! Есть следующий код: public partial class MainWindow : Window < .
Как зеркально отобразить dataGrid одного окна в dataGrid в другом окне?
Здравствуйте. Столкнулся с проблемой. Не знаю, как отобразить зеркально dataGrid одного окна, в.
DataGrid+ObjectDataProvider+DataTable после изменения источника обновить DataGrid
Окно с DataGrid 1. В ресурсах окна объявлен Instance датапровайдера с методом, возвращающим.
Удалить выбранную строку в DataGrid, если DataGrid содержит коллекцию
Здравствуйте! Скажите пожалуйсто, как удалить выбраную строку в DataGrid, если DataGrid содержит.
Master of Orion
6097 / 4953 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
Donix, попробуй
datagrid.ItemsSource = null;
Регистрация: 20.03.2011
Сообщений: 67
Psilon, спасибо. Но не помогло. У меня такая проблема: по нажатию кнопки в таблицу поступают данные. Если нажать ещё раз кнопку, то данные добавятся снова (ниже старых) и таблица растёт, а не обновляется 🙁
Master of Orion
6097 / 4953 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
Donix, всего 2 шага)
1) вместо обычных коллекций используйте ObservableCollection (тот же лист, но с плюшками)
2) напишите в конструкторе формы
datagrid.ItemsSource = myobservablecollection
после этого при обновлении данных в коллекции они будут автоматически обновляться в таблице. Вот небольшой пример моего проектика: посмотрите, как данные биндятся
Правда там листбокс, а не грид, но смысл тот же: один раз только идет привязка, потом вообще не идет работа с гридом, только с коллекцией. У меня еще пару раз вызываются методы тупо чтобы последний добавленный элемент выделялся, это не обязательно.
OrderToWord.rar (45.7 Кб, 42 просмотров) |
Регистрация: 20.03.2011
Сообщений: 67
Psilon, я как раз и использую ObservableCollection
109 / 50 / 14
Регистрация: 06.03.2012
Сообщений: 810
Donix, Что ты хочешь получить?
Пустой DataGrid или пустую коллекцию? Или после удаления элемента коллекции у тебя не сохраняется изменения?
Регистрация: 20.03.2011
Сообщений: 67
Jylik, сейчас объясню, что я хочу. Допустим я получаю какие-то два значения(числа, строки и т.д.) и при нажатии на Button они появляются в таблице(DataGrid)-вот это прекрасно работает у меня. А если я ещё раз нажму на Button, то полученные два новых значения(числа, строки и т.д.) не подставляются в таблицу вместо старых, а добавляются всё время ниже старых.
Master of Orion
6097 / 4953 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
Donix, код покажите, а то гладко было на бумаге.
Регистрация: 20.03.2011
Сообщений: 67
Psilon, вот код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } StopWatch StopWatch = new StopWatch(); public class Dannye { public double colFor { get; set; } public double colWhile { get; set; } } public ObservableCollectionDannye> dannye = new ObservableCollectionDannye>(); int temp = 0; int k = 0; string millisec1; string millisec2; public void For() { string str = myText.Text; StopWatch.startTimer(); for (int i = 0; i 500000; i++) { if (str == string.Empty) { temp++; } } StopWatch.stopTimer(); millisec1 = StopWatch.returnMillisec(); StopWatch.resetTimer(); } public void While() { string str = myText.Text; StopWatch.startTimer(); while (k 500000) { if (str == string.Empty) { temp++; } k++; } StopWatch.stopTimer(); millisec2 = StopWatch.returnMillisec(); StopWatch.resetTimer(); } public void ComboBox() { if (comboBox1.Text == "milliseconds") { double millisec11 = Convert.ToDouble(millisec1); double millisec22 = Convert.ToDouble(millisec2); dannye.Add(new Dannye() { colFor = millisec11, colWhile = millisec22, }); } } private void Button_Click_1(object sender, RoutedEventArgs e) { For(); While(); ComboBox(); MyDataGrid.ItemsSource = dannye; } }
109 / 50 / 14
Регистрация: 06.03.2012
Сообщений: 810
Donix, Да быть может тебе вместо таблицы использовать TextBlock?! Если тебе нужна только 1 строка?! из всего обЪекта.
1 2 3
Name="LoadString"> Здесь будут писаться имена: Text=""/>, а тут мы разместим их отчество: Text=""/>, а здесь мы напишем год рождения: Text=""/>. >
А затем просто помести полученные значения в строку «LoadString»
LoadString.DataContext = (получаемые сведения)
Например если это выделенный элемент коллекции, то можно написать так:
LoadString.DataContext = (dataGrid.SelectItem as Class1)
Взаимодействие с базой данных
SQLite является одной из наиболее используемых систем управления базами данных. Главным преимуществом SQLite является то, что для базы данных не нужно сервера. База данных представляет собой обычный локальный файл, который мы можем перемещать вместе с главным файлом приложения. Кроме того, для запросов к базе данных мы можем использовать стандартные выражения языка SQL, которые равным образом с некоторыми изменениями могут применяться и в других СУБД как Oracle, MS SQL Server, MySQL, Postgres и т.д.
Еще одним преимуществом является широкое распространение SQLite — область применения охватывает множество платфрм и технологий: WPF, Windows Forms, UWP, Android, iOS и т.д. И если мы, скажем, захотим создать копию приложения для ОС Android, то базу данных мы можем перенести в новое приложение такой, как она определена для приложения на WPF.
Но в данном случае для упрощения мы будет работать с базой данных SQLite через специальный ORM-фреймворк Entity Framework. В данном случае мы сосредоточимся на тех моментах, которые характерны для проекта WPF. Но при необходимости дополнительную информацию можно найти по следующим ссылкам: SQLite в C# и .NET и Руководство по Entity Framework
Итак, создадим новый проект WPF, который назовем SQLiteApp. В первую очередь нам надо добавить функциональность SQLite и Entity Framework в проект. Для этого необходимо добавить в проект через пакетный менеджер Nuget пакет Microsoft.EntityFrameworkCore.Sqlite . Итак, перейдем к Nuget, нажав в проекте правой кнопкой на узел Dependences и выбрав в открывшемся контекстном меню пункт Manage NuGet Packages. :
В окне менеджера Nuget введем в окно поиска «Microsoft.EntityFrameworkCore.Sqlite», и менеджер отобразит нам ряд результатов. Из них нам надо установить пакет под названием Microsoft.EntityFrameworkCore.Sqlite :
Итак, для работы с базой данных нам естественно понадобится сама база данных. Однако если у нас нет никакой БД, как в данном случае, мы можем воспользоваться подходом Code First, чтобы Entity Framework сам автоматически создал нам базу данных по определению используемых классов.
Вначале определим в проекте класс, объекты которого будут храниться в базе данных. Пусть это будет класс User :
namespace SQLiteApp < public class User < public int Id < get; set; >public string? Name < get; set; >public int Age < get; set; >> >
В данном случае класс User содержит свойство Id, которое будет выполнять роль уникального идентификатора пользователя. Кроме того, класс определяет свойство Name (имя пользователя) и Age (возраст пользователя).
Ключевым компонентом для взаимодействия с базой данных является контекст данных. Поэтому добавим в проект новый класс, который назовем ApplicationContext и который будет выполнять роль контекста данных:
using Microsoft.EntityFrameworkCore; namespace SQLiteApp < public class ApplicationContext : DbContext < public DbSetUsers = null!; protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) < optionsBuilder.UseSqlite("Data Source=helloapp.db"); >> >
Класс контекста должен наследоваться от DbContext. И для взаимодействия с таблицей, которая будет хранить данные объектов User, здесь также определено свойство Users . Чтобы указать анализатору кода, что данное свойство не будет равно null, свойству Users присваивается значение null!
Кроме того, чтобы связать контекст данных с конкретной базой данных, в методе OnConfiguring с помощью вызова
optionsBuilder.UseSqlite("Data Source=helloapp.db");
устанавливается используемая база данных. В частности методу UseSqlite передается строка подключения, в которой есть только один параметр — Data Source , который указывает на имя базы данных. То есть приложение будет использовать базу данных с именем «helloapp.db». Причем не важно, что сейчас такой базы данных не существует — она будет создана автоматически.
Теперь все готово для работы с базой данных. Стандартный набор операций по работе с БД включает получение объектов, добавление, изменение и удаление. Для получения и просмотра списка объектов из бд мы будем использовать главное окно. А для добавления и изменения создадим новое окно.
Итак, добавим в проект новое окно, которое назовем UserWindow.xaml . В итоге общая конфигурация проекта у нас будет выглядеть следующим образом:
В коде xaml у страницы UserWindow.xaml определим следующее содержимое:
<Window x:Class="SQLiteApp.UserWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="UserWindow" Height="200" Width="300"> <Window.Resources> <Style TargetType="TextBlock"> <Setter Property="Margin" Value="8" /> </Style> <Style TargetType="TextBox"> <Setter Property="Margin" Value="8" /> </Style> <Style TargetType="Button"> <Setter Property="MinWidth" Value="60" /> <Setter Property="Margin" Value="8" /> </Style> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="100" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <TextBlock Text="Имя" /> <TextBlock Text="Возраст" Grid.Row="1" /> <TextBox Text="" Grid.Column="1" /> <TextBox Text="" Grid.Column="1" Grid.Row="1" /> <StackPanel HorizontalAlignment="Center" Orientation="Horizontal" Grid.Row="3" Grid.Column="1"> <Button IsDefault="True" Click="Accept_Click" >OK</Button> <Button IsCancel="True" >Отмена</Button> </StackPanel> </Grid> </Window>
Здесь определены два поля ввода для каждого свойства модели User и две кнопки для сохранения и отмены.
В файле связанного кода UserWindow.xaml.cs определим контекст для этой страницы:
using System.Windows; namespace SQLiteApp < public partial class UserWindow : Window < public User User < get; private set; >public UserWindow(User user) < InitializeComponent(); User = user; DataContext = User; >void Accept_Click(object sender, RoutedEventArgs e) < DialogResult = true; >> >
Данное окно будет диалоговым. Через конструктор оно будет получать объект User, который устанавливается в качестве контекста данных.
В коде xaml у главного окна MainWindow определим вывод списка телефонов и набор кнопок для управления этим списком:
" FontSize="16" /> " FontSize="13" />
В коде C# у этого окна пропишем обработчики кнопок, через которые будем взаимодействовать с базой данных SQLite:
using Microsoft.EntityFrameworkCore; using System.Windows; namespace SQLiteApp < public partial class MainWindow : Window < ApplicationContext db = new ApplicationContext(); public MainWindow() < InitializeComponent(); Loaded += MainWindow_Loaded; >// при загрузке окна private void MainWindow_Loaded(object sender, RoutedEventArgs e) < // гарантируем, что база данных создана db.Database.EnsureCreated(); // загружаем данные из БД db.Users.Load(); // и устанавливаем данные в качестве контекста DataContext = db.Users.Local.ToObservableCollection(); >// добавление private void Add_Click(object sender, RoutedEventArgs e) < UserWindow UserWindow = new UserWindow(new User()); if (UserWindow.ShowDialog() == true) < User User = UserWindow.User; db.Users.Add(User); db.SaveChanges(); >> // редактирование private void Edit_Click(object sender, RoutedEventArgs e) < // получаем выделенный объект User? user = usersList.SelectedItem as User; // если ни одного объекта не выделено, выходим if (user is null) return; UserWindow UserWindow = new UserWindow(new User < Age = user.Age, Name = user.Name >); if (UserWindow.ShowDialog() == true) < // получаем измененный объект user = db.Users.Find(UserWindow.User.Id); if (user != null) < user.Age = UserWindow.User.Age; user.Name = UserWindow.User.Name; db.SaveChanges(); usersList.Items.Refresh(); >> > // удаление private void Delete_Click(object sender, RoutedEventArgs e) < // получаем выделенный объект User? user = usersList.SelectedItem as User; // если ни одного объекта не выделено, выходим if (user is null) return; db.Users.Remove(user); db.SaveChanges(); >> >
В коде класса прежде всего определяется переменная db, которая представляет контекст данных ApplicationContext и через которую будет идти взаимодействие с базой данных.
В конструкторе окна определяем обработчик загрузки окна, в котором, во-первых, гарантируем, что база данных создана, и для этого вызываем метод
db.Database.EnsureCreated();
В итоге даже если базы данных не существует, она будет создана в той же папке, где расположен файл приложения. Если бд уже имеется, тогда она просто будет использоваться.
Далее выражение db.Users.Load() загружает данные из таблицы Users в локальный кэш контекста данных. И затем список загруженных объектов устанавливается в качестве контекста данных:
DataContext = db.Users.Local.ToObservableCollection();
Для добавления вызывается метод Add:
db.Users.Add(user); db.SaveChanges();
Для удаления — метод Remove:
db.Users.Remove(user); db.SaveChanges();
При изменении мы передаем в UserWindow копию выбранного объекта. Если мы передавали бы сам выделенный объект, то все изменения на форме автоматически синхронизировались со списком, и не было бы смысла в кнопке отмены.
После получения измененного объекта мы находим его в базе данных и устанавливаем у него новые значения свойств, после чего сохраняем все изменения:
user = db.Users.Find(UserWindow.User.Id); if (user != null)
Здесь надо обратить внимание на вызов usersList.Items.Refresh() , который после обновления объекта в бд обновляется отображение списка. В качестве альтернативы мы бы могли реализовать интерфейс INotifyPropertyChanged и уведомлять систему при изменении значения свойства Name и/или Age.
Запустим приложение. И добавим какой нибудь объект:
И после добавления объект отобразится в списке: