WPF DataGrid选中行时显示文本框供用户输入订购数量的实现咨询
WPF DataGrid选中行显示订购数量输入框实现方法
你当前的代码将整列设为隐藏不符合需求,且DataGridTextColumn仅支持展示文本,无法直接作为输入控件使用,推荐用以下方案实现:
方案1:XAML触发器实现(推荐,无需复杂后台代码)
直接通过模板触发器判断行选中状态,自动控制输入框显隐,修改你的DataGrid列代码如下:
<DataGrid.Columns> <DataGridTextColumn Header="Id" Binding="{Binding ItemId}"/> <DataGridTextColumn Header="商品名称" Binding="{Binding Name}"/> <DataGridTextColumn Header="单价" Binding="{Binding Price, StringFormat={}{0:C}}"/> <DataGridTextColumn Header="库存数量" Binding="{Binding InStock}"/> <DataGridTemplateColumn Header="订购数量"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox x:Name="QuantityInput" Text="{Binding OrderQuantity, UpdateSourceTrigger=PropertyChanged}" Visibility="Collapsed" Width="100"/> <DataTemplate.Triggers> <!-- 绑定父级行的选中状态,选中时显示输入框 --> <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGridRow}, Path=IsSelected}" Value="True"> <Setter TargetName="QuantityInput" Property="Visibility" Value="Visible"/> </DataTrigger> </DataTemplate.Triggers> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns>
配套配置说明
- 你绑定的商品实体类需要新增
OrderQuantity属性,用来存储用户输入的订购数量,记得实现INotifyPropertyChanged接口保证绑定生效。 - 可新增输入校验限制只能输入正整数,给TextBox添加
PreviewTextInput事件,后台代码如下:
using System.Text.RegularExpressions; private void QuantityInput_PreviewTextInput(object sender, TextCompositionEventArgs e) { e.Handled = !Regex.IsMatch(e.Text, @"^\d+$"); }
方案2:后台事件实现(适合不想用触发器的场景)
如果偏好通过后台代码控制显隐,可使用DataGrid的SelectionChanged事件实现:
- 先将Quantity列改为上述的模板列,保留TextBox默认隐藏
- 给DataGrid添加
SelectionChanged事件,后台代码如下:
using System.Windows; using System.Windows.Controls; using System.Windows.Media; private void GoodsDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { // 隐藏所有行的输入框 foreach (var item in GoodsDataGrid.Items) { if (GoodsDataGrid.ItemContainerGenerator.ContainerFromItem(item) is DataGridRow row) { var inputBox = FindVisualChild<TextBox>(row, "QuantityInput"); if (inputBox != null) inputBox.Visibility = Visibility.Collapsed; } } // 显示选中行的输入框 if (GoodsDataGrid.SelectedItem != null) { var selectedRow = GoodsDataGrid.ItemContainerGenerator.ContainerFromItem(GoodsDataGrid.SelectedItem) as DataGridRow; var selectedInput = FindVisualChild<TextBox>(selectedRow, "QuantityInput"); if (selectedInput != null) selectedInput.Visibility = Visibility.Visible; } } // 辅助查找子控件的通用方法 private T FindVisualChild<T>(DependencyObject parent, string childName) where T : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var child = VisualTreeHelper.GetChild(parent, i); if (child is T target && (child as FrameworkElement)?.Name == childName) { return target; } var res = FindVisualChild<T>(child, childName); if (res != null) return res; } return null; }
优先推荐方案1,不需要操作视觉树,性能更稳定,代码维护成本更低。
内容的提问来源于stack exchange,提问作者Salar
相关产品推荐
相关产品推荐

