DataGridView 绑定

发布于 2024-07-14 10:44:10 字数 151 浏览 3 评论 0原文

我有一个通过通用列表绑定到的网格视图。 我自己设置了所有列。 我只是想:

在编辑行时捕获事件 PRE 格式错误 - 通过隐藏字段获取行信息 - 并坚持

我确信这一定很容易,但我没有对表单工作做太多工作,我不熟悉其 DataGridViews 事件。

I have a gridview that I am binding to via a generic list. I have set all the columns myself. I am just trying to:

Catch the event PRE format error when a row is edited- get the row information via a hidden field - and persist

I am sure this must be pretty easy but I haven't done much with forms work and I am unfamiliar with its DataGridViews Events.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

删除→记忆 2024-07-21 10:44:10

有两种看待这个问题的方法:

  • 处理 CellParsing 事件并解析该值
  • 在属性上使用自定义 TypeConverter

我通常更喜欢后者,因为它使此逻辑远离 UI; 我会看看是否可以做一个例子...


示例(大部分代码是“显示它工作”代码); 在这里,我定义了一个 MyDateTimeConverter,它将日期格式化/解析为其向后“dd MMM yyyy”文本(没有真正好的理由),并将该转换器与其中之一相关联特性。 您可以编辑网格中的值,更改将被推回(更改行以查看“实际”值更新)。 由于更改通知存在一些细微差别,它不会立即显示; 仅仅为此而使示例变得更加复杂是不值得的......

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Forms;

class Person
{
    public string Forename { get; set; }
    public string Surname { get; set; }

    [TypeConverter(typeof(MyDateTimeConverter))]
    public DateTime EditableValue { get { return ActualValue; } set { ActualValue = value; } }
    // this just proves what we have set...
    public DateTime ActualValue { get; private set; }
}
class MyDateTimeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
    }
    const string FORMAT = "dd MMM yyyy";
    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        if (value != null && value is string)
        {
            string s = (string)value;
            return DateTime.ParseExact(Reverse(s), FORMAT, CultureInfo.InvariantCulture);
        }
        return base.ConvertFrom(context, culture, value);
    }
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string))
        {
            return Reverse(((DateTime)value).ToString(FORMAT, CultureInfo.InvariantCulture));
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
    static string Reverse(string value)
    {
        char[] data = value.ToCharArray();
        Array.Reverse(data);
        return new string(data);
    }
}
class MyForm : Form
{
    public MyForm()
    {
        DataGridView grid = new DataGridView();
        grid.Dock = DockStyle.Fill;
        List<Person> people = new List<Person>();
        people.Add(new Person { Forename = "Fred", Surname = "Flintstone", EditableValue = DateTime.Today });
        people.Add(new Person { Forename = "Barney", Surname = "Rubble", EditableValue = DateTime.Today.AddDays(-25) });
        grid.DataSource = people;
        Controls.Add(grid);
    }
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new MyForm());
    }
}

There are two ways of looking at this;

  • handle the CellParsing event and parse the value
  • use a custom TypeConverter on the property

I usually prefer the latter, since it takes this logic away from the UI; I'll see if I can do an example...


Example (most of this code is the "show it working" code); here I define a MyDateTimeConverter, which formats/parses dates as their backwards "dd MMM yyyy" text (for no really good reason), and associate that converter with one of the properties. You can edit the values in the grid, and changes are pushed back in (change rows to see the "actual" value update). It doesn't show immediately because of some nuances around change-notification; it wasn't worth making the example more complex just for this...

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Forms;

class Person
{
    public string Forename { get; set; }
    public string Surname { get; set; }

    [TypeConverter(typeof(MyDateTimeConverter))]
    public DateTime EditableValue { get { return ActualValue; } set { ActualValue = value; } }
    // this just proves what we have set...
    public DateTime ActualValue { get; private set; }
}
class MyDateTimeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
    }
    const string FORMAT = "dd MMM yyyy";
    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        if (value != null && value is string)
        {
            string s = (string)value;
            return DateTime.ParseExact(Reverse(s), FORMAT, CultureInfo.InvariantCulture);
        }
        return base.ConvertFrom(context, culture, value);
    }
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string))
        {
            return Reverse(((DateTime)value).ToString(FORMAT, CultureInfo.InvariantCulture));
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
    static string Reverse(string value)
    {
        char[] data = value.ToCharArray();
        Array.Reverse(data);
        return new string(data);
    }
}
class MyForm : Form
{
    public MyForm()
    {
        DataGridView grid = new DataGridView();
        grid.Dock = DockStyle.Fill;
        List<Person> people = new List<Person>();
        people.Add(new Person { Forename = "Fred", Surname = "Flintstone", EditableValue = DateTime.Today });
        people.Add(new Person { Forename = "Barney", Surname = "Rubble", EditableValue = DateTime.Today.AddDays(-25) });
        grid.DataSource = people;
        Controls.Add(grid);
    }
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new MyForm());
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文