WPF DataGrid 指定列的数据可以编辑功能开发

需求:

如上图所示。最后两列的数据可以修改。在MVVM框架中还是很好实现的。

1.DataGrid 的数据源是用对应的ObservableCollection 的集合绑定。

2.修改要编辑列数据的列模板

复制代码
<DataGridTemplateColumn Width="120" Header="VernierOverlayX" HeaderStyle="{StaticResource ColumnHeaderStyle}">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <hc:NumericUpDown HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsEnabled="True" ValueFormat="N6" Value="{Binding VernierOverlayXInput, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="120" Header="VernierOverlayY" HeaderStyle="{StaticResource ColumnHeaderStyle}">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <hc:NumericUpDown HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsEnabled="True" ValueFormat="N6" Value="{Binding VernierOverlayYInput, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

关键功能说明

1. NumericUpDown 限制规则

  • ValueFormat="N6"最多保留 6 位小数
  • Value="{Binding ..., UpdateSourceTrigger=PropertyChanged}" → 输入实时同步到数据源
  • 自动限制只能输入数字 / 小数点,无法输入文字
  • 支持正负 float 数值

2. 实体类要求(ViewModel 绑定模型)

确保你的 TestResultDetail 模型里这两个字段是 float / double 类型:

复制代码
private float _vernierOverlayXInput;
/// <summary>
/// (用户从UI端输入)
/// </summary>
[MfFieldIgnore]
public float VernierOverlayXInput
{
    get => _vernierOverlayXInput;
    set
    {
        _vernierOverlayXInput = value;
        OnPropertyChanged();
    }
}

private float _vernierOverlayYInput;
/// <summary>
/// (用户从UI端输入)
/// </summary>
[MfFieldIgnore]
public float VernierOverlayYInput
{
    get => _vernierOverlayYInput;
    set
    {
        _vernierOverlayYInput = value;
        OnPropertyChanged();
    }
}

3. 保存功能实现(ViewModel 代码)

复制代码
using Microsoft.Toolkit.Mvvm;
using Microsoft.Toolkit.Mvvm.Input;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;

public class MainViewModel : ObservableObject
{
    // 绑定列表
    public ObservableCollection<TestResultDetail> TestResultDetailList { get; set; } = new();

    // 保存命令
    public IRelayCommand SaveDataCommand { get; }

    public MainViewModel()
    {
        // 初始化保存命令
        SaveDataCommand = new RelayCommand(SaveDataToFile);
    }

    // 保存逻辑(可改成保存到数据库/JSON/CSV)
    private void SaveDataToFile()
    {
        StringBuilder sb = new();
        // 写入表头
        sb.AppendLine("ShotPosition,PointPosition,TestNumber,X0,Y0,X180,Y180,TisX,TisY,CorrectionX,CorrectionY,VernierOverlayX,VernierOverlayY");
        
        // 写入每一行数据
        foreach (var item in TestResultDetailList)
        {
            sb.AppendLine($"{item.ShotData},{item.PointPosData},{item.TestNumber},{item.X0},{item.Y0},{item.X180},{item.Y180},{item.TisX},{item.TisY},{item.CorrectionX},{item.CorrectionY},{item.VernierOverlayX},{item.VernierOverlayY}");
        }

        // 保存到 CSV 文件
        File.WriteAllText("TestResultData.csv", sb.ToString(), Encoding.UTF8);

        // 提示保存成功(可替换为 MessageBox)
        Console.WriteLine("数据保存成功!");
    }
}
相关推荐
武藤一雄18 小时前
WPF中ViewModel之间的5种通讯方式
开发语言·前端·microsoft·c#·wpf
CSharp精选营1 天前
都是微软亲儿子,WPF凭啥干不掉WinForm?这3个场景说明白了
c#·wpf·跨平台·winform
baivfhpwxf20231 天前
wpf TextBlock 控件如何根据内容换行?
wpf
亘元有量-流量变现1 天前
鸿蒙、安卓、苹果音频设备技术深度解析与开发实践
android·wpf·harmonyos·亘元有量·积分墙
软泡芙1 天前
【Bug】ReactiveUI WPF绑定中依赖属性不更新的问题分析与解决方案
java·bug·wpf
浪扼飞舟1 天前
WPF输入验证(ValidationRule)
java·javascript·wpf
IOFsmLtzR3 天前
Flink Agents 源码解读 --- (5) --- ActionExecutionOperator
microsoft·flink·wpf
廋到被风吹走4 天前
【AI】Codex 复杂任务拆解:从“一气呵成“到“步步为营“
人工智能·wpf
希望永不加班4 天前
SpringBoot 整合 Redis 缓存
spring boot·redis·后端·缓存·wpf
_MyFavorite_4 天前
JAVA重点基础、进阶知识及易错点总结(29)JDK8 时间 API 进阶
java·开发语言·wpf