تعيين DataRow كعضو قيمة Combobox
سؤال
أقوم بملء العناصر على 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();
}