سؤال

أقوم بملء العناصر على Combobox من ملف XML باستخدام DataTable. حاليًا قمت بتعيينه بحيث يتم عرض عمود واحد من Combobox وآخر هو عضو في القيمة. ومع ذلك ، قد لا يعمل هذا دائمًا بالنسبة لي ، حيث يتعين علي تعيين المعلمة SelectiTem ، وقد لا يكون عضو القيمة فريدًا.

لا أعرف ما إذا كان هناك نسخة مكررة لعضو القيمة في الجدول أم لا ، لذلك كانت فكرتي هي أنني سأضع DataRow بأكملها كعضو قيمة في Combobox ثم استخدم comboBox.SelectedItem = (dataRow) some_data_row ؛ للاختيار ، وسيحدد دائمًا كائن Combobox الصحيح.

كيف يمكنني إنجاز هذا؟ هل هناك طريقة أفضل للقيام بذلك؟ أنا منفتح على الاقتراحات ، ولكن من المهم للغاية أن أتمكن من الوصول إلى كل من عضو العرض وعضو القيمة.

شكرا لك على مساعدتك!

تعديل: ربما لم أكن واضحًا بما فيه الكفاية من قبل ، ولكن بينما أسأل عما إذا كان هذا هو أفضل طريقة هنا ، أنا أسأل أيضًا كيف لفعل هذا. إذا لم أقم بتعيين معلمة ValueMember ، فإن SelectItem هو من نوع DataRowView ... يرجى ملاحظة ، أنني أريد استخدام المعلمة المحددة لتحديد العناصر من Combobox ، وإذا حاولت القيام بذلك دون تعيين عضو في القيمة بشكل صريح A تم طرح الاستثناء.

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

المحلول 2

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

ما فعلته هو أنني أنشأت فصلًا جديدًا ، في حالتي ، أطلق عليها اسم ListObject ، والذي كان يحتوي على خصائص dataRow (كما سترى لاحقًا أنه يعمل لأنواع أخرى أيضًا ، لقد استخدمت هذا للتو لأن هذا ما أردت فعليًا كعنصر الخاص بي خاصية القيمة). كما أنه يتجاوز الطرق:

  • سلسلة tostring ()
  • Bool يساوي (كائن OBJ)
  • int gethashcode () -ليست هناك حاجة في حالتي ، ولكن Visual Studio
    يحذرك يجب أن يتم تجاوزه.

كانت الفكرة أنه يمكنني ملء مجموعات combobox.items مع كائنات من صفي الخاص ، وعرض سلسلة مخصصة (إذا لم أكن قد عملت على هذا النحو ، فمن المحتمل أن يكون سؤالي التالي على Scack Overflow حول تخصيص أعضاء العرض عند قراءة العناصر من DataRow) وقارن عنصر فئة واحدة فقط (في حالة DataRow).

لذا ، إليك الكود ويعمل بشكل رائع (على الأقل لما أردت فعله به).

public class ListObject
{
    public DataRow element;

    public String DisplayObject = null;

    public ListObject(DataRow dr)
    {
        element = dr;
    }

    public ListObject(DataRow dr, String dspObject)
    {
        element = dr;
        DisplayObject = dspObject;
    }

    public override String ToString()
    {
        if (DisplayObject == null) throw new Exception("DisplayObject property was not set.");

        return element[DisplayObject].ToString();
    }

    public override bool Equals(object obj)
    {
        if (obj.GetType() == typeof(ListObject))
            return Equals(((ListObject)obj).element, this.element);
        else return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}

في حالتي ، يعمل بشكل رائع لأنني أستطيع فقط ملء Combobox ببيان foreach:

dtUsers.ReadXml(Program.Settings.xmlInputUsers);

foreach(DataRow dr in dtUsers.Rows) 
{
    cmbUser.Items.Add(new ListObject(dr, "Name"));
}

وعندما أحصل على dataRow ، أريد تحديد ذلك ، فأنا أقوم بذلك:

cmbUser.SelectedItem = new ListObject(dlg.SelectedDataRow);

حيث لا داعي للقلق بشأن عضو العرض وما إلى ذلك ، لأنه سيتم مقارنة DATAROW فقط ، وسيظل معلمات العرض الخاصة بك قد تم تعيينها عند ملء مجموعة Combobox.items. أيضًا نظرًا لأن طريقة tostring يتم تجاوزها ، يمكنك تخصيص إخراجك حقًا.

كان إنشاء هذا الفصل ممكنًا فقط بسبب مقالة MSDN على comboBox.SelectedItem الخاصية الذي لوحظ ، أن الخاصية المحددة هذه تعمل باستخدام طريقة الفهرس. تستخدم هذه الطريقة طريقة متساوية لتحديد المساواة.

نصائح أخرى

إذا قمت بربط أ ListBox إلى DataTable, ، أنت في الواقع تلتزم به DataView وهذا يمثل ذلك DataTable (DataTable الأدوات IListSource, وهذا يعيد أ DataView). لا يمكنك ضبط مباشرة SelectedItem إلى DataRow مثال ، عليك ضبطه على DataRowView نموذج. لسوء الحظ ، لا توجد طريقة سهلة للحصول على ملف DataRowView من DataRow.

من الأفضل أن تفعل كل تفاعلاتك من خلال DataRowView. هذا سيسمح لك بتعيين SelectedItem صراحة.

لا يمكنك استخدام SelectedValue الخاصية ، يجب استخدامك SelectedItem لهذا.

هذه هي الطريقة الأكثر بساطة للحصول على datatable إلى combobox

private void load() { 
DataTable dt = // get data from DB 
comboBox1.ValueMember = null; // allows you to get all fields in the obj to combobox
comboBox1.DisplayMember = "ccType";//label displayed from dt
comboBox1.DataSource = dt;
}
//to test 
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {

        DataRowView current = (DataRowView)comboBox1.SelectedValue;
        string drs = current.Row["ID"].ToString();

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