سؤال

أنا أحاول أن لا بد DataGridViewComboBoxColumn إلى مثيل فو ، ولكن عند تعيين قيمة على الشبكة لدي ArgumentException تقول لي أنني لا يمكن تحويل من سلسلة فو.

var data = (from item in someTable
            select new { Foo = item.foo, Bar = item.Bar }).ToList();
grid.DataSource = data;
column.DataPropertyName = "Foo";
column.DataSource = (from foo in Foo select foo).ToList (); //foo is an instance of Foo
column.DisplayMember = "SomeNameField"; //Foo.SomeNameField contains a description of the instance

أنا في عداد المفقودين شيئا ؟ هل من الممكن أن databind إلى كائن معقد?

تحديث:

لقد نفذت TypeConverter و overrided CanConvertFrom, CanConvertTo, ConvertTo, ConvertFrom.أنا الآن الحصول على

FormatException:على DataGridViewComboBoxCell قيمة غير صالحة

أي أفكار ؟

هل كانت مفيدة؟

المحلول

كنت في عداد المفقودين قطعة ممكن.

column.DataPropertyName = "Foo";
column.DisplayMember = "SomeNameField"; 
column.ValueMember = "Bar"; // must do this, empty string causes it to be 
                            // of type string, basically the display value
                            // probably a bug in .NET
column.DataSource = from foo in Foo select foo;
grid.DataSource = data;

تحديث:

في الحقيقة بعد قراءة السؤال مرة أخرى, أعتقد أنك تواجه أنه أشار إلى علة.هناك للأسف لا يوجد طريقة لجعله العودة لا بد كائن دون استخدام مخصص TypeDescriptor/TypeConverter/BindingSource.

الجواب الملزمة إلى كائن معقد.لا افتراضيا.كتبت لطيفة جدا من المشروع الحالي.هذا ينطوي على اتخاذ مخصص TypeDescriptor/TypeConverter/BindingSource أن يعود كل متداخلة خصائص.آخر " علة " أنت غير قادر على استخدام '.' لعضو فاصل ، اضطررت إلى اللجوء إلى ':' بدلا من ذلك.

نصائح أخرى

على DataGridViewComboBoxColumn يجب أن يكون دائما جميع القيم الممكنة في مربع تحرير وسرد عناصر قائمة أو أنه سوف رمي "FormatException:على DataGridViewComboBoxCell قيمة غير صالحة".

إذا كنت في محاولة للحصول على العودة القيم اختيارها من مربع تحرير وسرد العمود ، يمكنك التعامل مع DataGridView CellParsing الحدث ، والحصول على العنصر المحدد من DataGridView.EditingControl لأنه سيتم تعيين لتحرير التحكم من تحرير العمود.هنا هو على سبيل المثال:

private void dataGridView1_CellParsing(object sender, 
 DataGridViewCellParsingEventArgs e) {
   if (dataGridView1.CurrentCell.OwningColumn is DataGridViewComboBoxColumn) {
       DataGridViewComboBoxEditingControl editingControl = 
                (DataGridViewComboBoxEditingControl)dataGridView1.EditingControl;
       e.Value = editingControl.SelectedItem;
       e.ParsingApplied = true;
   }
}

يمكنك أيضا تخصيص طريقة عرض الكائنات تظهر في كل خلية من التعامل مع تنسيق الخلية الحدث هنا هو رمز العرض toString لأي كائن أو واجهة.

private void dataGridView1_CellFormatting(object sender, 
    DataGridViewCellFormattingEventArgs e) {
        if (e.Value != null) {
            e.Value = e.Value.ToString();
            e.FormattingApplied = true;
        }
    } 

مقابض اثنين من هذه الأحداث ينبغي أن يكون كافيا للحصول على عرض وتحرير البيانات في أي bussiness كائن و easer ثم كتابة نوع المحولات.هذا العمل تحدد لك DataGridView و لك مربع تحرير وسرد العمود كما يلي:

var data = (from item in someTable
        select new { Foo = item.foo, Bar = item.Bar }).ToList();
grid.DataSource = data;
column.DataPropertyName = "Foo";
column.DataSource = (from foo in Foo select foo).ToList ();

لا DisplayMember أو ValueMember الملكية تحتاج إلى تعيين, فقط تأكد من أن مربع تحرير وسرد مصدر البيانات في قائمة جميع القيم الممكنة ل فو.

وآمل في أن يساعد.

في الواقع يمكنك استخدام نوع معقد في DataGridViewComboBoxColumn.

على سبيل المثال:

DataGridViewComboBoxColumn.DataPropertyName = "ValueMode";
DataGridViewComboBoxColumn.DisplayMember = "Label";
DataGridViewComboBoxColumn.ValueMember = "Self"; *
DataGridViewComboBoxColumn.ValueType = typeof(ValueModeItem);

Self هو:

public ValueModeItem Self
{
    get
    {
        return this;
    }
}

مهم جدا - تحتاج إلى تجاوز 'يساوي' طريقة معقدة نوع.في حالتي:

public override bool Equals(object obj)
{
    if (obj is ValueModeItem && obj != null)
    {
        if (...)
            return true;
    }
    return false;
}

كنت constantely ضرب نفس المشكلة حتى أنا discovert أنه لا يمكنك تعيين DisplayMember من DataGridViewComboBoxCell دون تحديد ValueMember أيضا.
في نفس الطريق, وضع ValueMember وليس DisplayMember فشل أيضا عليك أن تحدد أي أو كليهما.

النموذج الخاص بك هو فو ، وأنت بالتأكيد تريد أن قيمة مربع تحرير وسرد يكون العنصر نفسه.من أجل القيام بذلك, أبسط طريقة هي أيضا إنشاء الملكية في فو ، العودة نفسها.

public class Foo
{
    ...
    public Foo This { get {return this; } }
}

ثم ربط يصبح:

column.DataPropertyName = "Foo";
column.DataSource = (from foo in Foo select foo).ToList (); //foo is an instance of Foo
column.DisplayMember = "SomeNameField"; //Foo.SomeNameField contains a description of the instance
column.ValueMember = "This";

هذا يجب أن تعمل ، وقيمة الخلية يجب أن تكون من نوع فو كما هو متوقع.

مثيرة للاهتمام المرجعية: مشاكل مع DataGridViewComboBoxColumn

ومع ذلك ، فإن DataGridViewComboBoxColumn لا يعمل مثل هذا ، على الرغم من أنه سيتم عرض ToString قيمة إذا لم يكن تعيين DisplayMember شيئا داخليا خطأ عندما يحاول تبدو حتى SelectedItem ، DisplayMember العامة الملكية الفئة.والأسوأ من ذلك هو السلوك الافتراضي إذا كنت لا تعيين ValueMember الملكية للعودة DisplayMember هناك لا توجد طريقة للحصول على البند الفعلية نفسها.العمل فقط حول إضافة الملكية الفئة الخاصة بك أن يعود نفسه ووضع تلك الممتلكات على ValueMember.بالطبع, إذا كان البند الخاص بك ليست شيئا كنت قادرا على إلى تغيير (مثل واحد من اطار الطبقات) عليك أن cludge معا كائن حاوية الذي يحمل إشارة إلى البند الخاص بك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top