3

いくつかの数値データを使用し て にDataGridViewバインドしました。確実に機能させるには、次の 2 つが必要です。DataTable

  1. 数値を含むすべての列の数値ソート ( doubles/ )、ints
  2. 特別な場合に数字の代わりにテキスト (「x」や「-」など) を追加する可能性。

DataTable のレベルでそれらを追加できる簡単な方法はありますか?

DataTableの列のタイプを に変更できることはわかってStringいますが、既に組み込まれている方法で列を並べ替えるためだけに、さらに多くのコードを追加する必要があります。また、グリフの方法を変更する必要はありません。描かれたものなど

また、DGV が生成される量と方法が原因で、取得した DGV ごとに 1 つのメソッドを追加するほど簡単ではありません。

[編集]

私は同じ DataTables のセットを Excel ファイルに書き込むので、それらが動作する方法を大幅に変更すると問題が発生し、エラーが発生しやすくなります。これは避けたいと思います。

ほとんどの場合、dataTables を埋めるための私のコードは次のようになります。

var row = MyDataTable.GetMyDataTableNewRow();  
row.partName = part.name;  
row.weight = part.weight.ToString();  // it's double  
row.quantity = part.GetParentSet().FindQuantities(part.name).ToString(); // it's int  
row.maxsize = part.CalculateMaxSize().ToString();  
MyDataTable.AddMyDataTableRow(row);
4

2 に答える 2

4

レベルで目的の動作を定義する唯一の方法DataTableは、double と string の両方を保持するカスタム タイプを導入し、適切な を定義することTypeConverterです (オブジェクトを正しく表示し、 で編集できるようにするためDataGridView)。

例:

[TypeConverter(typeof(DoubleOrTextConverter))]
public class DoubleOrText : IComparable
{
    public double Value { get; private set; }
    public string Text { get; private set; }
    public DoubleOrText(double val, string text)
    {
        this.Value = val;
        this.Text = text;
    }
    public static DoubleOrText FromString(System.Globalization.CultureInfo culture, string str)
    {
        double v;
        if (double.TryParse(str, out v))
            return new DoubleOrText(v, null);
        return new DoubleOrText(0, str);
    }
    public string ToString(System.Globalization.CultureInfo culture)
    {
        if (this.Text != null)
            return this.Text;
        return this.Value.ToString(culture);
    }
    // define your sorting strategy here
    public int CompareTo(object obj)
    {
        if (obj == null) return 1;

        var other = obj as DoubleOrText;
        if (other != null)
            return this.Value.CompareTo(other.Value);
        else
            throw new ArgumentException("Object is not a DoubleOrText");
    }
}

public class DoubleOrTextConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string))
            return true;
        return base.CanConvertFrom(context, sourceType);
    }
    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        if (value is string)
            return DoubleOrText.FromString(culture, value as string);
        return base.ConvertFrom(context, culture, value);
    }
    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string))
        {
            var dValue = (DoubleOrText)value;
            return dValue.ToString(culture);
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

使用例:

DataTable dt = new DataTable();
dt.Columns.Add("Column 1", typeof(DoubleOrText));

dt.Rows.Add(new DoubleOrText(0.0, null));
dt.Rows.Add(new DoubleOrText(1.0, "X"));
dt.Rows.Add(new DoubleOrText(2.3, "-"));
dt.Rows.Add(new DoubleOrText(4.1, null));

this.dataGridView1.DataSource = dt;

結果:

ここに画像の説明を入力

于 2012-08-08T14:37:38.403 に答える
1

を使用するDataGridViewと、列をテキストに変更せずに数値列の一部の値を特別に変更するケースを処理する UI レベルで書式設定を適用できます。

これは、 のCellFormattingおよびCellParsingイベントを使用して実現されDataGridViewます。

たとえば、データ テーブルに int 列があり、1 のすべてのインスタンスを x として表示し、3 のすべてのインスタンスを y として表示したいとします。

CellFormatting次のようにイベントを使用します。

void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    if (dataGridView1.Columns[e.ColumnIndex].Name == "CustomerID")
    {
        if (int.Parse(e.Value.ToString()) == 1)
        {
            e.Value = "x";
        }
        else if (int.Parse(e.Value.ToString()) == 3)
        {
            e.Value = "y";
        }
    }
}

このアプローチでは、基礎となるデータ テーブルは基礎となるセルの値と同様に変更されないため、書式設定は数値 1 と 3 があるかのように機能します。

次に、イベント内で何らかの処理を行ってCellParsing、文字列を元に戻す必要があります。これもまた、基になるテーブルにまだ数値列があるためです。

次のようなものは、解析される値が int に変換されない場合に、セルの実際の値を使用するだけです。ただし、このハンドラーで必要なことは何でもできます。

void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
{
    int parsedValue = 0;
    if (!int.TryParse(e.Value.ToString(), out parsedValue))
    {
        if (int.TryParse(dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString(), out parsedValue))
            e.Value = parsedValue;
        else
            e.Value = 0;

        e.ParsingApplied = true;
    }

} 
于 2012-08-08T16:56:20.117 に答える