Finally, I found a solution that does not have the above problems.
I made a strategic mistake. When we connect
DataGrid.ItemsSource
to
DataView
or
CollectionViewSource.Source
for the first time, the values of
DataView
and
CollectionViewSource.Source
change automatically with each change (like insert, edit, and delete), so the code that connects
DataGrid.ItemsSource
to
DataView
or
CollectionViewSource.Source
does not need to be rewritten.
Look carefully at the image below to get a better understanding of how this feature works. When
DataGrid.ItemsSource
changes in the first window,
DataGrid.ItemsSource
in the second window also changes.
Click on this link to view the image
I tested the following codes in different situations, using nearly the entire capacity of the
MS Access database.
The conditions are as follows:
Number of records = 252,500
Database size = 2,094,128 KB (database size without any rows = 604 KB)
Size of each row = (Database size - database size without any rows) / Number of records => about 8.291184 KB (Of course, if I haven't made a mistake)
Hardware and software used in the test =
Acer Aspire 5750G Laptop (Core i5 2nd Gen/4 GB RAM/Win7-x64),
Visual Studio 2017,
.NET Framework 4.5.2,
WPF
<Window.Resources>
<local:DatabaseDataSet x:Key="Database_DataSet"/>
<CollectionViewSource x:Key="BookTableViewSource" Source="{Binding BookTable, Source={StaticResource Database_DataSet}}"/>
<CollectionViewSource x:Key="MemberTableViewSource" Source="{Binding MemberTable, Source={StaticResource Database_DataSet}}"/>
</Window.Resources>
<Grid DataContext="{StaticResource BookTableViewSource}" Width="486" Height="386">
<DataGrid x:Name="BookDataGrid" HeadersVisibility="Column" EnableRowVirtualization="True" VirtualizingPanel.ScrollUnit="Pixel" CanUserAddRows="False" AutoGenerateColumns="False" ItemsSource="{Binding}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="486" Height="386" Margin="0">
<DataGrid.Columns>
<DataGridTextColumn x:Name="BookName" Binding="{Binding BookName}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="Publisher" Binding="{Binding Publisher}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="Category" Binding="{Binding Category}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="BookCode" Binding="{Binding BookCode}" IsReadOnly="True" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="Inventory" Binding="{Binding Inventory}" IsReadOnly="True" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="ReleaseDate" Binding="{Binding ReleaseDate}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="DateTaken" Binding="{Binding DateTaken}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="ReturnDate" Binding="{Binding ReturnDate}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="RecipientName" Binding="{Binding RecipientName}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="Language" Binding="{Binding BookLanguage}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="Length" Binding="{Binding Length}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="Form" Binding="{Binding Form}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="Translator" Binding="{Binding Translator}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="Narrator" Binding="{Binding Narrator}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="ISBN" Binding="{Binding ISBN}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="Location" Binding="{Binding Location}" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="Price" Binding="{Binding Price}" Width="SizeToHeader"/>
<DataGridTemplateColumn x:Name="BookImage" Width="SizeToHeader">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image x:Name="BookImg" Source="{Binding BookImage}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
public DataView BDV = new DataView();
object[] BookCodeSelectedItems = null;
object[] ISBN_Value = null;
public MainWindow()
{
InitializeComponent();
BDV = BookDataGrid.ItemsSource as DataView;
}
private void DataGridDeleteMenu_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
switch (BookDataGrid.SelectedItems.Count > 0)
{
case false:
MessageWindow MW = new MessageWindow();
MW.YesButton.Visibility = Visibility.Hidden;
MW.NoButton.Visibility = Visibility.Hidden;
MW.MessageLabel.Margin = new Thickness(0, 110, 0, 0);
MW.MessageLabel.HorizontalAlignment = HorizontalAlignment.Center;
MW.Image.Source = GetImageFromBytes(System.IO.File.ReadAllBytes(System.Windows.Forms.Application.StartupPath + @"\Images\Warning.bin"));
MW.MessageTextBlock.Text = "No rows selected";
MW.OKButton.Content = "OK";
MW.ShowDialog();
break;
default:
var stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
List<object> Row = new List<object>();
for (int i = 0; i < BookDataGrid.Items.Count; i++)
{
Row.Add(BookDataGrid.Items[i]);
}
BookCodeSelectedItems = new object[BookDataGrid.SelectedItems.Count];
ISBN_Value = new string[BookDataGrid.SelectedItems.Count];
int j = 0;
foreach (DataRowView DRV in BookDataGrid.SelectedItems)
{
BookCodeSelectedItems[j] = BDV.Table.Rows[BDV.Table.Rows.IndexOf(DRV.Row)][3];
ISBN_Value[j] = BDV.Table.Rows[BDV.Table.Rows.IndexOf(DRV.Row)][14];
}
for (int i = 0; i < BookDataGrid.SelectedItems.Count; i++)
{
Row.Remove(BookDataGrid.SelectedItems[i]);
}
BookDataGrid.ItemsSource = Row;
stopwatch.Stop();
MessageBox.Show("Total seconds: " + stopwatch.Elapsed.TotalSeconds.ToString());
break;
}
}
Output:
Click this link to view the output
I also tried the following code, it was very slow. It took more than
10 minutes and I stopped the app. But
List<>
took about
16 seconds.
var stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
for (int i = BookDataGrid.SelectedItems.Count - 1; i >= 0; i--)
{
BDV.Table.Rows.Remove(((DataRowView)BookDataGrid.SelectedItems[i]).Row);
}
BookDataGrid.ItemsSource = BDV.Table.DefaultView;
stopwatch.Stop();
MessageBox.Show("Total seconds: " + stopwatch.Elapsed.TotalSeconds.ToString());
I hope this is the most comprehensive solution for converting
DataGrid.ItemsSource
to
DataTable
,
DataView
or another type of data source.
Thank you for your attention.