我正在开发一个 WPF 应用程序,并创建了两个数据网格,如附图所示。第二个数据网格是使用 CreateCoachCompositionDataGrid() 方法动态创建的。还有另一个名为 UpdateCoachCompositionDataGrid() 方法,用于根据 dataGridTrainHome(第一个数据网格)的 SelectionChanged 事件更新数据网格的 UI(单元格的背景颜色、组合框启用/禁用等) ).
我一直面临的问题是,当我从 dataGridTrainHome 中选择一行时,数据网格的 UI 没有更新。但是,我确信 UpdateCoachCompositionDataGrid() 方法正在被调用,因为标签(火车编号、火车名称、站台编号)正在更新。
我不知道问题是什么。
我用来创建数据网格的方法:
private void CreateCoachCompositionDataGrid()
{
// Clear the existing columns in the data grid
dataGridCoachComposition.Columns.Clear();
// Set the margin for the data grid
dataGridCoachComposition.Margin = new Thickness(16, 468, 230, 18);
// Hide the column headers
dataGridCoachComposition.HeadersVisibility = DataGridHeadersVisibility.None;
// Set the row height
dataGridCoachComposition.RowHeight = 50; // Set this to your desired row height
// Set the vertical alignment to top to remove empty space at the bottom
dataGridCoachComposition.VerticalAlignment = VerticalAlignment.Top;
// Create 14 columns
for (int i = 1; i <= 14; i++)
{
// Create a new DataGridTemplateColumn
DataGridTemplateColumn column = new DataGridTemplateColumn();
column.Width = new DataGridLength(1, DataGridLengthUnitType.Star); // Set the column width to fill the available space
// Create a DataTemplate for the cell template
DataTemplate cellTemplate = new DataTemplate();
// Create a StackPanel to hold the TextBlock and ComboBox
FrameworkElementFactory stackPanel = new FrameworkElementFactory(typeof(StackPanel));
stackPanel.SetValue(StackPanel.OrientationProperty, Orientation.Vertical);
// Create a TextBlock for the coach number
FrameworkElementFactory textBlock = new FrameworkElementFactory(typeof(TextBlock));
textBlock.SetValue(TextBlock.TextProperty, "C" + i.ToString("00"));
textBlock.SetValue(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Center); // Center the text block horizontally
stackPanel.AppendChild(textBlock);
// Create a ComboBox for the coach type
FrameworkElementFactory comboBox = new FrameworkElementFactory(typeof(ComboBox));
comboBox.SetValue(ComboBox.ItemsSourceProperty, new string[] { "ENG", "HIN" });
comboBox.SetValue(FrameworkElement.MarginProperty, new Thickness(5)); // Set a margin around the ComboBox
stackPanel.AppendChild(comboBox);
// Set the cell template's visual tree to the StackPanel
cellTemplate.VisualTree = stackPanel;
// Set the column's cell template
column.CellTemplate = cellTemplate;
// Add the column to the data grid
dataGridCoachComposition.Columns.Add(column);
}
// Add two empty rows to the data grid
dataGridCoachComposition.Items.Add(new object());
dataGridCoachComposition.Items.Add(new object());
}
我用来更新数据网格的方法:
private void UpdateCoachCompositionDataGrid(DataRow selectedRow)
{
// Get the TrainNumber, TrainName, and PlatformNumber from the selected row
string trainNumber = selectedRow["TrainNumber"].ToString();
string trainName = selectedRow["TrainName"].ToString();
string platformNumber = selectedRow["PlatformNumber"].ToString();
// Display train information in the labels
lblTrainNo.Content = "Train Number: " + trainNumber;
lblTrainName.Content = "Train Name: " + trainName;
lblPlatformNo.Content = "Platform Number: " + platformNumber;
// Get the coach numbers from the database
List<string> coachNumbers = GetCoachNumbersFromDatabase(trainNumber);
// Iterate over each cell in the data grid
for (int i = 0; i < dataGridCoachComposition.Columns.Count; i++)
{
for (int j = 0; j < dataGridCoachComposition.Items.Count; j++)
{
// Get the cell content
var cellContent = dataGridCoachComposition.Columns[i].GetCellContent(dataGridCoachComposition.Items[j]);
// Get the StackPanel in the cell
StackPanel stackPanel = cellContent as StackPanel;
if (stackPanel != null)
{
// Get the ComboBox in the StackPanel
ComboBox comboBox = stackPanel.Children.OfType<ComboBox>().FirstOrDefault();
if (comboBox != null)
{
// Check if the coach number is present
if (coachNumbers.Contains("C" + (i + 1 + j * 14).ToString("00")))
{
// Auto-populate the ComboBox with 'ENG'
comboBox.SelectedIndex = 0;
// Enable the ComboBox
comboBox.IsEnabled = true;
// Set the cell background to white
((DataGridCell)cellContent.Parent).Background = new SolidColorBrush(Colors.White);
}
else
{
// Clear the ComboBox selection
comboBox.SelectedIndex = -1;
// Disable the ComboBox
comboBox.IsEnabled = false;
// Set the cell background to grey
((DataGridCell)cellContent.Parent).Background = new SolidColorBrush(Colors.Gray);
}
}
}
}
}
}
通过以下方式调用 UpdateCoachCompositionDataGrid():
private void dataGridTrainHome_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Get the currently selected items in the DataGrid
var selectedRows = dataGridTrainHome.SelectedItems;
// If any rows are selected
if (selectedRows != null && selectedRows.Count > 0)
{
// Get the last selected row
DataRowView lastSelectedRow = (DataRowView)selectedRows[selectedRows.Count - 1];
// Use the Dispatcher to delay the call to UpdateCoachCompositionDataGrid
Dispatcher.BeginInvoke(new Action(() =>
{
// Update the coach composition DataGrid
UpdateCoachCompositionDataGrid(lastSelectedRow.Row);
}), DispatcherPriority.Render);
}
}
我尝试使用 dataGridCoachComposition.UpdateLayout() 强制更新数据网格的 UI。没成功。
我还尝试从 DataTable 创建 DataView,然后更新数据网格的 UI。但是,这也没有改变任何事情。
问题在于:
StackPanel stackPanel = cellContent as StackPanel
始终为 null,因为 cellContent 返回 ContentPresenter
您可以轻松更改代码部分以查看可视化树:
var stackPanel =VisualTreeHelper.GetChild(cellContent, 0) as StackPanel;
零表示寻找第一个孩子。
这不是非常稳定的解决方案,因为如果您将 StackPanel 更改为其他布局,系统将崩溃。
我建议使用 DataTable 和后来的 MVVM 来轻松更新网格状态。
它对我有用。