如何在运行时修改WPF DataGridTextColumn的数值精度
WPF动态修改DataGrid数值显示精度的几种实现方法
方案一:带参数的绑定转换器(推荐MVVM场景)
这种方法无需修改实体类,通过转换器接收动态精度参数,实现数值格式化的动态更新。
首先实现数值格式化转换器:
public class NumberFormatConverter : IValueConverter { // 正向转换:将数值按指定精度转为字符串 public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is double num && parameter is int precision) { return num.ToString($"N{precision}", culture); } return value?.ToString() ?? string.Empty; } // 反向转换:支持编辑场景(可选) public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (double.TryParse(value?.ToString(), out double num)) { return num; } return DependencyProperty.UnsetValue; } }
在ViewModel中维护精度属性,并通知绑定刷新:
public class MainViewModel : INotifyPropertyChanged { private int _decimalPrecision = 2; // 默认保留2位小数 public int DecimalPrecision { get => _decimalPrecision; set { _decimalPrecision = value; OnPropertyChanged(nameof(DecimalPrecision)); // 触发DataGrid所有行的绑定刷新 OnPropertyChanged(nameof(TableItems)); } } // 精度选项,供ComboBox选择 public List<int> DecimalPrecisionOptions { get; } = new List<int> { 0, 1, 2, 3, 4, 5 }; public ObservableCollection<TableItem> TableItems { get; } = new ObservableCollection<TableItem>(); public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
XAML中配置资源和绑定:
<Window.Resources> <local:NumberFormatConverter x:Key="NumberFormatConverter"/> </Window.Resources> <!-- ComboBox和确定按钮 --> <StackPanel Orientation="Horizontal" Margin="10"> <ComboBox Width="80" ItemsSource="{Binding DecimalPrecisionOptions}" SelectedItem="{Binding DecimalPrecision}"/> <Button Content="确定" Margin="10,0"/> </StackPanel> <!-- DataGrid列绑定 --> <DataGrid ItemsSource="{Binding TableItems}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Width="100" Header="Test1" Binding="{Binding Test1, Converter={StaticResource NumberFormatConverter}, ConverterParameter={Binding DataContext.DecimalPrecision, RelativeSource={RelativeSource AncestorType=DataGrid}}}" IsReadOnly="True"/> </DataGrid.Columns> </DataGrid>
当选择精度点击确定时,ViewModel的DecimalPrecision更新,触发TableItems的属性变更通知,DataGrid会重新调用转换器,用新精度格式化所有数值。
方案二:直接修改列的绑定StringFormat(贴近WinForm思路)
这种方法直接操作DataGrid列的绑定属性,和WinForm的实现逻辑类似,适合快速开发或非MVVM场景。
先给DataGrid列命名:
<DataGrid x:Name="dataGrid" ItemsSource="{Binding TableItems}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn x:Name="Test1Column" Width="100" Header="Test1" Binding="{Binding Test1}" IsReadOnly="True"/> </DataGrid.Columns> </DataGrid> <StackPanel Orientation="Horizontal" Margin="10"> <ComboBox x:Name="precisionComboBox" Width="80" ItemsSource="{Binding DecimalPrecisionOptions}"/> <Button Content="确定" Margin="10,0" Click="ConfirmButton_Click"/> </StackPanel>
按钮点击事件中更新格式:
private void ConfirmButton_Click(object sender, RoutedEventArgs e) { if (int.TryParse(precisionComboBox.SelectedItem.ToString(), out int acc)) { var binding = Test1Column.Binding as Binding; if (binding != null) { binding.StringFormat = $"N{acc}"; // 重新赋值绑定并刷新列 Test1Column.Binding = binding; dataGrid.Items.Refresh(); } } }
方案三:优化你自己的实体类方案
你之前通过实体类生成格式化字符串的思路可行,但可以优化为共享精度参数,避免每个实体都维护一份精度值:
使用多绑定绑定数值和全局精度,配合多值转换器:
public class NumberFormatMultiConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values.Length == 2 && values[0] is double num && values[1] is int precision) { return num.ToString($"N{precision}", culture); } return string.Empty; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); // 只读场景无需实现 } }
XAML中配置多绑定:
<Window.Resources> <local:NumberFormatMultiConverter x:Key="NumberFormatMultiConverter"/> </Window.Resources> <DataGridTextColumn Width="100" Header="Test1" IsReadOnly="True"> <DataGridTextColumn.Binding> <MultiBinding Converter="{StaticResource NumberFormatMultiConverter}"> <Binding Path="Test1"/> <Binding Path="DataContext.DecimalPrecision" RelativeSource="{RelativeSource AncestorType=DataGrid}"/> </MultiBinding> </DataGridTextColumn.Binding> </DataGridTextColumn>
这样实体类无需额外维护Acc和Test1Str,只保留核心的Test1属性即可,更符合单一职责原则。
内容的提问来源于stack exchange,提问作者ChaoJiale
相关产品推荐
相关产品推荐

