簡體   English   中英

如何在數據表行中存儲多個列對象

[英]How to store multple columns object in DataTable Row

如何在擴展為幾列的數據表行中存儲對象,或者如何在一列中存儲對象,而在另一列中引用該對象的屬性?

class MyDataTable : DataTable
{
    public MyDataTable
    {
        this.Columns.Add("col1");
        this.Columns.Add("col2")        
        this.Columns.Add("Cat", typeof(Cat))
        this.Columns.Add("CatType")

        Cat cat1 = new Cat("name1", "type1")
        Cat cat2 = new Cat("name2", "type2")
        this.Rows.add(new object[] {"value","value",cat1,cat1.type} )
        this.Rows.add(new object[] {"value","value",cat2,cat2.type} )

        // I want to show table like: 
        // |value|value|name1|type1|
        // |value|value|name2|type2|

        // while type should be a reference not a static string, so
        cat1.type = "type3"; //should be able to change table like:

        // |value|value|name1|type3|
        // |value|value|name2|type2|    
    }
} 

class Cat
{
    string name;
    string type;
    public Cat(...){..}

    public override string toString()
        return name;
}

或者也許像在桌子上擺桌子?:

class MyDataTable : DataTable
{
    public MyDataTable
    {
        this.Columns.Add("col1");
        this.Columns.Add("col2")        
        this.Columns.Add("Cat", typeof(Cat))

        Cat cat1 = new Cat("name1", "type1")
        Cat cat2 = new Cat("name2", "type2")
        this.Rows.add(new object[] {"value","value",cat1} )
        this.Rows.add(new object[] {"value","value",cat2} )

        // And show table like: 
        // |value|value||name1|type1||
        // |value|value||name2|type2||
    }
} 

 class Cat : DataTable {
      public Cat(string name, string type){
        this.Columns.Add("name");
        this.Columns.Add("type");
        this.Rows.Add(name,type);
      } 
 }

但能夠顯示Cat列:

 datagridview1.DataSource = new MyDataTable();

////

@rene答案

當我同時將'type'設置為LiveString時:

datagridview.datasource = new List<Cat>(...)

並嘗試從與該對象關聯的datagridview GUI單元進行編輯,我得到:

System.FormatException: Invalid cast from 'System.String' to 'syb_con.LiveString'. ---> System.InvalidCastException: Invalid cast from 'System.String' to 'syb_con.LiveString'.

  at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)

   at System.String.System.IConvertible.ToType(Type type, IFormatProvider provider)

   at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)

   at System.Windows.Forms.Formatter.ChangeType(Object value, Type type, IFormatProvider formatInfo)

   --- End of inner exception stack trace ---

   at System.Windows.Forms.Formatter.ChangeType(Object value, Type type, IFormatProvider formatInfo)

   at System.Windows.Forms.Formatter.ParseObjectInternal(Object value, Type targetType, Type sourceType, TypeConverter targetConverter, TypeConverter sourceConverter, IFormatProvider formatInfo, Object formattedNullValue)

   at System.Windows.Forms.Formatter.ParseObject(Object value, Type targetType, Type sourceType, TypeConverter targetConverter, TypeConverter sourceConverter, IFormatProvider formatInfo, Object formattedNullValue, Object dataSourceNullValue)

   at System.Windows.Forms.DataGridViewCell.ParseFormattedValueInternal(Type valueType, Object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)

   at System.Windows.Forms.DataGridViewCell.ParseFormattedValue(Object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)

   at System.Windows.Forms.DataGridView.PushFormattedValue(DataGridViewCell& dataGridViewCurrentCell, Object formattedValue, Exception& exception)

DataTable實際上旨在在將行添加到狀態時存儲狀態。 您的用例似乎超出了其設計能力。

如果允許我們將Type屬性的不可變類型字符串替換為允許更改其值的類型,則用於添加對象的技巧也可以用於該類型。 我們使用以下事實:對於Object類型的DataColumns,Row將在該對象上調用ToString

我將介紹一種名為LiveString的新類型

class LiveString 
{
    string value;

    internal string Value {
        get{return value;}
        set{this.value= value;}
    }

    public LiveString(string value) {
       this.value = value;
    }

    // use an implicit operator
    public static implicit operator LiveString(string value)
    {
        return new LiveString(value);
    }

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

目的是包裝一個字符串,並具有從字符串創建新對象的方法,還可以獲取和更改其內部狀態。 我使用了轉換運算符,因此Cat類的當前用戶不必更改其大量代碼。

您必須按照以下方式修改代碼:

class MyDataTable : DataTable
{
    public MyDataTable()
    {
        this.Columns.Add("col1");
        this.Columns.Add("col2");        
        this.Columns.Add("Cat", typeof(Cat));
        // notice the typeof here
        this.Columns.Add("CatType", typeof(LiveString));

        Cat cat1 = new Cat("name1", "type1");
        Cat cat2 = new Cat("name2", "type2");
        this.Rows.Add(new object[] {"value","value",cat1,cat1.type} );
        this.Rows.Add(new object[] {"value","value",cat2,cat2.type} );

        cat1.type = "type3"; 
    }
} 

還有你的貓課。 請注意,在類型的setter上,如何不替換_type上的當前對象,而僅替換它的Value 這樣可以保證Row所擁有的實例得到更新,而不是被不存儲或更新在Row中的新實例替換。

class Cat
{
    string name;
    LiveString _type;
    public LiveString type {
        get 
        { 
            return _type;
        }
        set 
        {
            _type.Value = value.Value;
        }
    }

    public Cat(string name, string type){this.name= name; this._type = type;}

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

本示例嘗試盡可能接近DataTable的使用。 相反,您可以構建自己的集合,並使用有關其持有的類型以及如何表示它們的元數據來提供數據。 我認為lambda表達式在該實現空間中可能很有用。 其他選擇可能是使用反射

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM