#c# #wpf #sorting #datatable #datagridview
#c# #wpf #сортировка #datatable #datagridview
Вопрос:
Я создал приложение для заметок в WPF с помощью C # для учебных целей.
Я ввел некоторые данные и сохранил их в datatable, который является datagridview в WPF. Данные состоят из заголовка, который вы помещаете в текстовое поле «Заголовок», и сообщения, которое вы помещаете в текстовое поле «Сообщение». Теперь я хотел бы прочитать данные, которые я ввел. Итак, когда я выбираю первую строку и нажимаю «Прочитать», в текстовом поле заголовка появляется «1», а в текстовом поле «Сообщение» — «a», то же самое выполняется при выборе 2-й и 3-й строк.
Теперь я нажимаю на «Заголовок», чтобы отсортировать представление таблицы данных, и снова выбираю 3-ю строку, которая отображается в datagridview как «1», и нажимаю «Прочитать». Ну, как вы можете видеть, появляется число «3», а не «1» … поэтому кажется, что datagridview был отсортирован, но не datatable, содержащий значения…
Я понятия не имею, как это решить, так как поиск решения мне не помог…Наверное, я просто не понял документы Microsoft well…so Я подумал, что вы могли бы мне помочь?
Заранее спасибо, и вот часть кода cs и xaml:
cs-код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;
using System.Data;
using System.ComponentModel;
namespace NoteTaking_App
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
DataTable table;
int indexSelected; //Index of selected row
//indexSelected = dgrid_data.SelectedIndex;
private void MB(string text, string title)
{
MessageBox.Show(text, title, MessageBoxButton.OK, MessageBoxImage.Information);
}
public MainWindow()
{
InitializeComponent();
}
private void form_Main_Loaded(object sender, RoutedEventArgs e)
{
table = new DataTable();
table.Columns.Add("Title", typeof(String));
table.Columns.Add("Message", typeof(String));
dgrid_data.ItemsSource = table.DefaultView;
dgrid_data.Columns[1].Visibility = Visibility.Collapsed;
}
private void bttn_new_Click(object sender, RoutedEventArgs e)
{
txt_message.Clear();
txt_title.Clear();
}
private void bttn_save_Click(object sender, RoutedEventArgs e)
{
if (String.IsNullOrWhiteSpace(txt_title.Text))
{
MB("Please put in a Title", "title missing");
}
else
{
table.Rows.Add(txt_title.Text, txt_message.Text);
txt_message.Clear();
txt_title.Clear();
}
}
private void bttn_read_Click(object sender, RoutedEventArgs e)
{
indexSelected = dgrid_data.SelectedIndex;
if (indexSelected > -1)
{
txt_title.Text = table.Rows[indexSelected].ItemArray[0].ToString();
txt_message.Text = table.Rows[indexSelected].ItemArray[1].ToString();
}
else if (table.Rows.Count ==0)
{
MB("There are no saved rows to read", "Selection missing");
}
else
{
MB("Please select a row", "Selection missing");
}
}
private void bttn_delete_Click(object sender, RoutedEventArgs e)
{
indexSelected = dgrid_data.SelectedIndex;
if (indexSelected > -1)
{
this.table.Rows[indexSelected].Delete();
}
else if (table.Rows.Count == 0)
{
MB("There are no saved rows to delete", "Selection missing");
}
else
{
MB("Please select a row", "Selection missing");
}
}
}
}
код xaml
<Window x:Class="NoteTaking_App.MainWindow"
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"
xmlns:local="clr-namespace:NoteTaking_App"
mc:Ignorable="d"
Title="Note Taking" Height="450" Width="800">
<Grid x:Name="form_Main" Loaded="form_Main_Loaded">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="117*"/>
<ColumnDefinition Width="220*"/>
<ColumnDefinition Width="63*"/>
</Grid.ColumnDefinitions>
<DataGrid x:Name="dgrid_data" Grid.Column="1" HorizontalAlignment="Left" Height="263" Margin="192,36,0,0" VerticalAlignment="Top" Width="372" RenderTransformOrigin="0.554,0.552" Grid.ColumnSpan="2" HeadersVisibility="Column" HorizontalScrollBarVisibility="Disabled" UseLayoutRounding="True" CanUserReorderColumns="False" ColumnWidth="*" IsReadOnly="True" IsSynchronizedWithCurrentItem="False" >
<DataGrid.RowHeaderStyle>
<Style/>
</DataGrid.RowHeaderStyle>
<DataGrid.ColumnHeaderStyle>
<Style/>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
<TextBox x:Name="txt_message" Grid.ColumnSpan="2" HorizontalAlignment="Left" Height="183" Margin="109,116,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="275" RenderTransformOrigin="0.5,0.5" AcceptsReturn="True" AcceptsTab="True">
<TextBox.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="0"/>
<TranslateTransform/>
</TransformGroup>
</TextBox.RenderTransform>
</TextBox>
<Button x:Name="bttn_new" Content="New" HorizontalAlignment="Left" Height="31" Margin="109,352,0,0" VerticalAlignment="Top" Width="102" Click="bttn_new_Click"/>
<Button x:Name="bttn_save" Content="Save" HorizontalAlignment="Left" Height="31" Margin="48,352,0,0" VerticalAlignment="Top" Width="102" Grid.Column="1" Click="bttn_save_Click"/>
<Button x:Name="bttn_read" Content="Read" HorizontalAlignment="Left" Height="31" Margin="246,352,0,0" VerticalAlignment="Top" Width="102" Grid.Column="1" Click="bttn_read_Click"/>
<Button x:Name="bttn_delete" Content="Delete" HorizontalAlignment="Left" Height="31" Margin="402,352,0,0" VerticalAlignment="Top" Width="102" Grid.Column="1" Click="bttn_delete_Click" Grid.ColumnSpan="2"/>
<Label x:Name="lbl_titel" Content="Title" HorizontalAlignment="Left" Height="48" Margin="12,41,0,0" VerticalAlignment="Top" Width="89" AutomationProperties.Name="Titel"/>
<Label x:Name="lbl_message" Content="Message" HorizontalAlignment="Left" Height="44" Margin="12,109,0,0" VerticalAlignment="Top" Width="89"/>
<TextBox x:Name="txt_title" Grid.ColumnSpan="2" HorizontalAlignment="Left" Height="41" Margin="108,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="275"/>
</Grid>
Окончательный код после реализации ответа
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;
using System.Data;
using System.ComponentModel;
namespace NoteTaking_App
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
DataTable table;
private void MB(string text, string title)
{
MessageBox.Show(text, title, MessageBoxButton.OK, MessageBoxImage.Information);
}
public MainWindow()
{
InitializeComponent();
DataRowView dataRowView = (DataRowView)dgrid_data.SelectedItem;
}
private void form_Main_Loaded(object sender, RoutedEventArgs e)
{
table = new DataTable();
table.Columns.Add("Title", typeof(String));
table.Columns.Add("Message", typeof(String));
dgrid_data.ItemsSource = table.DefaultView;
dgrid_data.Columns[1].Visibility = Visibility.Collapsed;
}
private void bttn_new_Click(object sender, RoutedEventArgs e)
{
txt_message.Clear();
txt_title.Clear();
}
private void bttn_save_Click(object sender, RoutedEventArgs e)
{
if (String.IsNullOrWhiteSpace(txt_title.Text))
{
MB("Please put in a Title", "title missing");
}
else
{
table.Rows.Add(txt_title.Text, txt_message.Text);
txt_message.Clear();
txt_title.Clear();
}
}
private void bttn_read_Click(object sender, RoutedEventArgs e)
{
DataRowView dataRowView = (DataRowView)dgrid_data.SelectedItem;
if (dataRowView!=null)
{
txt_title.Text = dataRowView[0].ToString();
txt_message.Text = dataRowView[1].ToString();
}
else if (table.Rows.Count == 0)
{
MB("There are no saved rows to read", "Selection missing");
}
else
{
MB("Please select a row", "Selection missing");
}
}
private void bttn_delete_Click(object sender, RoutedEventArgs e)
{
DataRowView dataRowView = (DataRowView)dgrid_data.SelectedItem;
if (dataRowView!=null)
{
dataRowView.Delete();
}
else if (table.Rows.Count == 0)
{
MB("There are no saved rows to delete", "Selection missing");
}
else
{
MB("Please select a row", "Selection missing");
}
}
}
}
Комментарии:
1. Вы отсортировали свою коллекцию, но не изменили выбранный элемент
2. Я не понимаю, о чем вы говорите .. разве я не сделал этого, нажав на другую строку?
Ответ №1:
Приведите SelectedItem
к a DataRowView
и получите оттуда значения столбцов:
private void bttn_read_Click(object sender, RoutedEventArgs e)
{
DataRowView drv = dgrid_data.SelectedItem as DataRowView;
if (drv != null)
{
txt_title.Text = drv[0].ToString();
txt_message.Text = drv[0].ToString();
}
else if (table.Rows.Count == 0)
{
MB("There are no saved rows to read", "Selection missing");
}
else
{
MB("Please select a row", "Selection missing");
}
}
То же самое, когда вы удаляете, т.Е. Используете SelectedItem
свойство DataGrid
.
Комментарии:
1. Большое вам спасибо, работает как шарм! У меня есть еще 3 вопроса / вопроса, которые я хотел бы затронуть (из-за лучшего обзора каждого в каждом комментарии)
2. txt_message. Текст = drv[0]. toString(); должно быть txt_message. Текст = drv[1]. toString(); Я знаю, что вы просто забыли изменить…
3. Поскольку нам нужно использовать DataRowView drv = dgrid_data. SelectedItem как DataRowView; также для bttn_delete_Click есть ли лучший способ определить его вне метода bttn_read_Click? Я попробовал сам, но это не сработало, чего я и ожидал … Впрочем, возможно, я сделал что-то не так…
4. была ли более глубокая цель написания DataRowView drv = dgrid_data. SelectedItem как DataRowView; вместо DataRowView drv = (DataRowView)dgrid_data. SelectedItem; ? Я имею в виду, что оба варианта работают так, как я пробовал, но я бы предпочел (DataRowView)dgrid_data. SelectedItem; поскольку он выдает ошибку исключения, если что-то пойдет не так…
Ответ №2:
Сортировка в пользовательском интерфейсе не изменяет индексы. Используйте SelectedItem вместо SelectedIndex
Комментарии:
1. Извините, но мои знания ограничены: из следующей части кода, как мне правильно отобразить заголовок и сообщение: txt_title. Текст = таблица. Строки [выбран индекс]. itemArray[0] . toString(); (это из события bttn_read_Click)
2. Я имел в виду dgrid_data. SelectedItem
3. это не так просто: SelectedItem — это объект, а не int — это приводит к вопросу, как я могу получить доступ к «Заголовку» и «Сообщению» в моем datagridview и поместить их в текстовые поля?