我有一个C# WPF项目,将数据从DataGrid
保存到SQL Server数据库中的表中
在数据库中,我有两个表Factor
和Commodity
,这两个表相互关联,并且是x1c 0d1x
由ObservableCollection
填充的数据网格ItemsSource
被命名为WHOLE_DATA_FACTOR
,它来自Factor
表
和DataGridComboBoxColumn
的ItemsSource
在加载程序时仅填充一次,在RowEditEnding
事件中插入Factor
表后,我想重新加载数据网格的数据,DataGridComboBoxColumn
项曾经被SELECT CommodityCode, CommodityName FROM dbo.Commodity
中的一个查询填充过,但是我注意到在LoadDataAgian
之后,集合中的项开始刷新(就像在每个项上移动一样),这使得程序变慢,并且DataGridComboBoxColumn
x 1 m15n1x再次开始填充,而我没有这样做
以下是发生的视频:
完整源代码和数据库:https://ufile.io/uxneng9r
XAML:
<DataGridComboBoxColumn Width="160" Header="DataGridComboBoxColumn"
SelectedValueBinding="{Binding CommodityID}"
DisplayMemberPath="CommodityName"
SelectedValuePath="CommodityCode"
>
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding Path=TheCommodityCombo_DATA, RelativeSource={RelativeSource AncestorType=Window}}" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding Path=TheCommodityCombo_DATA, RelativeSource={RelativeSource AncestorType=Window}}" />
<Setter Property="IsEditable" Value="True"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
<DataGridComboBoxColumn Width="200" Header="Status ComboBoxColumn"
SelectedValueBinding="{Binding STATUS}"
DisplayMemberPath="STATUS_NAME"
SelectedValuePath="STATUS">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding Path=DataContext.STATUS_COMBO_DATA, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding Path=DataContext.STATUS_COMBO_DATA, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
<Setter Property="IsEditable" Value="True"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
</DataGrid.Columns>
</DataGrid>
代码隐藏:
public partial class MainWindow : Window
{
/// <summary>
/// For Ensuring the new data is getting in Row end edit
/// </summary>
private bool _handle = true;
MyerEntities dbms = new MyerEntities();
#region Models and Collections
/// <summary>
/// For Factor Table
/// </summary>
public class MyCustomModel_Factor
{
public long? NUMBER { get; set; }
public string CustomerName { get; set; }
public long? CommodityID { get; set; }
public long? STATUS { get; set; }
}
public ObservableCollection<MyCustomModel_Factor> WHOLE_DATA_FACTOR { get; set; } = new ObservableCollection<MyCustomModel_Factor>();
/// <summary>
/// For Commodity Table for ComboBox Items
/// </summary>
public ObservableCollection<MyCustomModel_Commodity> TheCommodityCombo_DATA { get; set; } = new ObservableCollection<MyCustomModel_Commodity>();
public class MyCustomModel_Commodity
{
public long CommodityCode { get; set; }
public string CommodityName { get; set; }
}
//STATUS
public ObservableCollection<CutsomStatus_Model> STATUS_COMBO_DATA { get; set; } = new ObservableCollection<CutsomStatus_Model>();
public class CutsomStatus_Model
{
public long? STATUS { get; set; }
public string STATUS_NAME { get; set; }
}
#endregion
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//Filling DataGrid by ObservableCollection
WHOLE_DATA_FACTOR.Clear();
var RST = dbms.Database.SqlQuery<MyCustomModel_Factor>("SELECT * FROM Factor").ToList();
foreach (var item in RST)
{ WHOLE_DATA_FACTOR.Add(item); }
//Filling ComboBox from Another Table that Related to Factor Table
TheCommodityCombo_DATA.Clear();
var RST2 = dbms.Database.SqlQuery<MyCustomModel_Commodity>("SELECT CommodityCode, CommodityName FROM dbo.Commodity").ToList();
foreach (var item2 in RST2)
{
TheCommodityCombo_DATA.Add(item2);
}
//STATUS Filling
STATUS_COMBO_DATA.Add(new CutsomStatus_Model { STATUS = 1, STATUS_NAME = "Undone" });
STATUS_COMBO_DATA.Add(new CutsomStatus_Model { STATUS = 2, STATUS_NAME = "Done" });
STATUS_COMBO_DATA.Add(new CutsomStatus_Model { STATUS = 3, STATUS_NAME = "Canceled" });
}
private void MainDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
try
{
var WhatWasRow = e.Row.Item as MyCustomModel_Factor;
var TheCurrentColumnName = MainDataGrid.CurrentColumn.SortMemberPath;
var test = WhatWasRow.GetType().GetProperty(TheCurrentColumnName).GetValue(WhatWasRow);
var Editedrow = (e.EditingElement as ComboBox);
var test3 = ((System.Windows.Controls.Primitives.Selector)e.EditingElement).SelectedValue;
}
catch (Exception)
{ goto OnErrorResumeNext; }
OnErrorResumeNext:;
}
private void MainDataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
if (_handle)
{
_handle = false;
MainDataGrid.CommitEdit();
var ROW_ITM = e.Row.Item as MyCustomModel_Factor;
//...Do Insert
dbms.Database.ExecuteSqlCommand($"INSERT INTO dbo.Factor (CustomerName,CommodityID,STATUS) VALUES (N'{ROW_ITM.CustomerName}',{ROW_ITM.CommodityID},{ROW_ITM.STATUS})");
//I think i need somthing like this ↓_________________________________
//ObservableCollection.WHOLE_DATA_FACTOR.IsEnabled = false;
//ObservableCollection.TheCommodityCombo_DATA.IsEnabled = false;
//ObservableCollection.STATUS_COMBO_DATA.IsEnabled = false;
LoadDataAgian();
_handle = true;
//ObservableCollection.WHOLE_DATA_FACTOR.IsEnabled = true;
//ObservableCollection.TheCommodityCombo_DATA.IsEnabled = true;
//ObservableCollection.STATUS_COMBO_DATA.IsEnabled = true;
//_______________________________________________________________________
return;
//After this line , most stop continue ,
//but it will go for → ObservableCollections property { get; set; } to refreshing every item , it feels Requery
}
}
private void LoadDataAgian()
{
WHOLE_DATA_FACTOR.Clear();
var RST = dbms.Database.SqlQuery<MyCustomModel_Factor>("SELECT * FROM Factor").ToList();
foreach (var item in RST)
{ WHOLE_DATA_FACTOR.Add(item); }
}
}
相关链接:Updating an ObservableCollection in WPF causes screen flicker; How can I prevent it?
Can I somehow temporarily disable WPF data binding changes?
更新:-DatGrid
的ItemsSource
由Factor
表填充-DataGridComboBoxColumn
的ItemsSource
由Commoditiy
填充
当我想按"select * from Factor"
实现DataGrid的数据时,我只重新加载了DataGrid的ItemsSource,而不是DataGridComboBoxColumn的ItemsSource为什么DataGridComboBoxColumn的ItemsSource将刷新(就像在每个项目上移动一样)
注意:如果解释不好,请检查视频和评论在我的代码
致上
1条答案
按热度按时间cqoc49vn1#
无论何时修改(添加/删除)
ObservableCollection
,Target
都会被触发,并开始调用集合项的getter{set; get;}
来更新自己。如果这种行为不能满足您的需要,您可以执行以下操作:
1.将
ObservableCollection
替换为List
。1.让类实现
INotifyPropertyChanged
接口,如下所示(基于您的代码):1.无论何时您想从代码更新UI,都可以使用
OnPropertyChanged
显式地完成:注意,我已经创建了一个
new List<MyCustomModel_Commodity>()
,所以要更新绑定到List
的Target
,必须给予它一个新的引用,也可以在调用OnPropertyChanged
之前执行WHOLE_DATA_FACTOR = WHOLE_DATA_FACTOR.ToList()