我有C# WPF專案,它將資料保存DataGrid到 SQL Server 資料庫中的表中
在資料庫中,我有兩個相互關聯的
表Factor和Commodity
ItemsSource由 an 填充的 DataGridObservableCollection命名WHOLE_DATA_FACTOR為來自FactorTable
并且ItemsSource在DataGridComboBoxColumn加載程式時僅填充一次,在我插入Factor表中RowEditEnding事件后,我想為 DataGrid 重新加載資料,
這些DataGridComboBoxColumn專案由 中的查詢填充一次SELECT CommodityCode, CommodityName FROM dbo.Commodity,但我注意到在 之后LoadDataAgian,集合中的專案開始重繪 (好像在每個專案上移動),這使程式變慢,并且DataGridComboBoxColumn ItemsSource開始填充再次,雖然我沒有那樣做
這是發生了什么的視頻:
mp4:https ://ufile.io/p5azjp40
完整的源代碼和資料庫: 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 one rrorResumeNext; }
one rrorResumeNext:;
}
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); }
}
}
相關鏈接: 在 WPF 中更新 ObservableCollection 會導致螢屏閃爍;我該如何預防?
我可以以某種方式暫時禁用 WPF 資料系結更改嗎?
更新: -ItemsSource的DatGrid從Factor表中填充 -ItemsSource的DataGridComboBoxColumn填充有Commoditiy
當我想重新加載 DataGrid 的資料時,"select * from Factor"我只重新加載了 DataGrid 的 ItemsSource 而不是 DataGridComboBoxColumn 的 ItemsSource 為什么 DataGridComboBoxColumn 的 ItemsSource 會重繪 (好像在每個專案上移動)
注意:如果解釋不好,請查看我的代碼中的視頻和評論
此致
uj5u.com熱心網友回復:
每當您修改(添加/洗掉) 時ObservableCollection,Target都會觸發 并開始呼叫{set; get;}集合專案的 getter 以更新自身。
如果此行為不能滿足您的需求,您可以執行以下操作:
替換
ObservableCollection為List。讓類實作
INotifyPropertyChanged介面,如下所示(基于您的代碼):
public partial class MainWindow : Window, INotifyPropertyChanged {
// ..
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// ..
}
- 每當您想從代碼更新 UI 時,您都可以使用以下命令顯式執行此操作
OnPropertyChanged:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//Filling DataGrid by ObservableCollection
WHOLE_DATA_FACTOR = new List<MyCustomModel_Commodity>();
var RST = dbms.Database.SqlQuery<MyCustomModel_Factor>("SELECT * FROM Factor").ToList();
foreach (var item in RST)
WHOLE_DATA_FACTOR.Add(item);
OnPropertyChanged(nameof(WHOLE_DATA_FACTOR));
// ..
}
請注意,我創建了 a new List<MyCustomModel_Commodity>(),因此要更新Target 系結到 a List,您必須給它一個新的參考,您也可以WHOLE_DATA_FACTOR = WHOLE_DATA_FACTOR.ToList()在呼叫之前執行OnPropertyChanged
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/504931.html
上一篇:C#正則運算式匹配
