21

次のオブジェクト Car を gridview にバインドするにはどうすればよいですか?

一般クラスの車
{
   長い ID {get; 設定;}
   メーカー メーカー {get; 設定;}
}

パブリック クラス メーカー
{
   長い ID {get; 設定;}
   文字列名 {get; 設定;}
}

プリミティブ型は簡単にバインドできますが、Maker で何かを表示する方法が見つかりません。私は、Manufacturer.Name を表示したいと思います。それは可能ですか?

それを行う方法は何ですか?ManufacturerId を Car にも保存してから、製造元のリストを使用して lookupEditRepository をセットアップする必要がありますか?

4

8 に答える 8

28

わかりましたみんな...この質問はすぐに投稿されましたが、cell_formattingイベントでリフレクションを使用してネストされたプロパティを取得することで、これを行うためのかなり素晴らしく簡単な方法を見つけました。

次のようになります。

    private void Grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {

        DataGridView grid = (DataGridView)sender;
        DataGridViewRow row = grid.Rows[e.RowIndex];
        DataGridViewColumn col = grid.Columns[e.ColumnIndex];
        if (row.DataBoundItem != null && col.DataPropertyName.Contains("."))
        {
            string[] props = col.DataPropertyName.Split('.');
            PropertyInfo propInfo = row.DataBoundItem.GetType().GetProperty(props[0]);
            object val = propInfo.GetValue(row.DataBoundItem, null);
            for (int i = 1; i < props.Length; i++)
            {
                propInfo = val.GetType().GetProperty(props[i]);
                val = propInfo.GetValue(val, null);
            }
            e.Value = val;
        }
    }

以上です!列の DataPropertyName で使い慣れた構文 "ParentProp.ChildProp.GrandChildProp" を使用できるようになりました。

于 2012-05-12T22:44:01.810 に答える
12

はい、TypeDescriptionProvider を作成して、ネストされたバインディングを実現できます。MSDN ブログの詳細な例を次に示します。

http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column-to-a-second-level-property-of-a-data-source。 aspx

于 2008-09-23T14:30:22.387 に答える
8

最近のアプリケーションでこれにアプローチした方法は、DataGridViewTextBoxColumn や DataGridViewTextBoxCell などの既存のクラスの 1 つを継承して、独自の DataGridViewColumn および DataGridViewCell クラスを作成することでした。

必要なセルのタイプに応じて、Button、Checkbox、ComboBox などを使用できます。System.Windows.Forms で使用できるタイプを見てください。

セルは値をオブジェクトとして処理するため、Car クラスをセルの値に渡すことができます。

SetValue と GetValue をオーバーライドすると、値を処理するために必要なロジックを追加できます。

例えば:

public class CarCell : System.Windows.Forms.DataGridViewTextBoxCell
{
    protected override object GetValue(int rowIndex)
    {
        Car car = base.GetValue(rowIndex) as Car;
        if (car != null)
        {
            return car.Maker.Name;
        }
        else
        {
            return "";
        }
    }
}

列クラスで行う必要がある主なことは、CellTemplate をカスタム セル クラスに設定することです。

public class CarColumn : System.Windows.Forms.DataGridViewTextBoxColumn
{
    public CarColumn(): base()
    {
        CarCell c = new CarCell();
        base.CellTemplate = c;
    }
}

これらのカスタム列/セルを DataGridView で使用することにより、DataGridView に多くの追加機能を追加できます。

GetFormattedValue をオーバーライドして文字列値にカスタム書式を適用することで、表示される書式を変更するためにそれらを使用しました。

また、Paint をオーバーライドして、値の条件に応じてカスタム セルの強調表示を行い、セルの Style.BackColor を値に基づいて必要なものに変更しました。

于 2008-09-24T18:26:53.823 に答える
5
    public class Manufacturer
    {
       long Id {get; set;}
       String Name {get; set;}

       public override string ToString()
       {
          return Name;
       }
    }

to string メソッドをオーバーライドします。

于 2008-09-23T14:27:20.507 に答える
2

これが私が働いた別のオプションです:

<asp:TemplateColumn
    HeaderText="Maker">
    <ItemTemplate>
          <%#Eval("Maker.Name")%>
    </ItemTemplate>
</asp:TemplateColumn>

ASP.NET 4.0 固有のものかもしれませんが、魅力的に機能します!

于 2011-03-09T18:30:25.530 に答える
2

特定の入れ子になったプロパティをバインド ターゲットとして公開する場合は、Ben Hoffstein の回答 ( http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column- to-a-second-level-property-of-a-data-source.aspx ) はかなり良いです。参照された記事は少し鈍いですが、うまくいきます。

列を複雑なプロパティ (メーカーなど) にバインドしてレンダリング ロジックをオーバーライドするだけの場合は、ManiacXZ が推奨する方法を実行するか、BoundField をサブクラス化して FormatDataValue() のカスタム実装を提供します。これは、ToString(); のオーバーライドに似ています。オブジェクト参照を取得し、グリッドに表示する文字列を返します。

このようなもの:

public class ManufacturerField : BoundField
{
    protected override string FormatDataValue(object dataValue, bool encode)
    {
        var mfr = dataValue as Manufacturer;

        if (mfr != null)
        {
            return mfr.Name + " (ID " + mfr.Id + ")";
        }
        else
        {
            return base.FormatDataValue(dataValue, encode);
        }
    }
}

データ フィールドとして "Manufacturer" を指定して、ManufacturerField をグリッドに追加するだけで準備完了です。

于 2008-10-01T01:36:55.370 に答える
2

リストを使用して、DataMemberを文字列「Maker.Name」に設定するだけです。DataKeyFieldで車の ID を使用する場合は、それを「ID」に設定します。

dataGrid.DataSource = carList;
dataGrid.DataMember = "Maker.Name";
dataGrid.DataKeyField = "ID";
dataGrid.DataBind();

少なくともリピーター制御で機能することは知っています...

于 2008-09-23T14:31:43.070 に答える
1

私はあなたが次のことができると仮定します:

public class Car
{
    public long Id {get; set;}
    public Manufacturer Maker {private get; set;}

    public string ManufacturerName
    {
       get { return Maker != null ? Maker.Name : ""; }
    }
}

public class Manufacturer
{
   long Id {get; set;}
   String Name {get; set;}
}
于 2009-06-02T16:25:08.480 に答える