private void PopulateListView(ListView listView, SelectedObject selObj) { SuspendLayout(); // Get all fields from mdc. uint[] uflids; // First find out how many there are. int flidSize = MetaDataCache.GetFields(selObj.m_clid, true, (int)CellarModuleDefns.kgrfcptAll, 0, null); // Now get them for real. using (ArrayPtr flids = MarshalEx.ArrayToNative(flidSize, typeof(uint))) { flidSize = MetaDataCache.GetFields(selObj.m_clid, true, (int)CellarModuleDefns.kgrfcptAll, flidSize, flids); uflids = (uint[])MarshalEx.NativeToArray(flids, flidSize, typeof(uint)); } List <ListViewItem> list = new List <ListViewItem>(); foreach (uint flid in uflids) { if (flid > 0) { string classname; string fieldname = MetaDataCache.GetFieldName(flid); ListViewItem lvi = new ListViewItem(fieldname, 0); // listView.Items.Add(fieldname); list.Add(lvi); lvi.Tag = flid; // TODO: Show some kind of data in the second column of the lvi. // For basic data types, just show the data, if it exists (NA, if not). // Selecting a basic data type field, will clear the right panel. // For objects, we need to distinguish between owning/reference and atomic/seq/coll: // Just use the FDO 'standard' of OA, OS, OC, RA, RS, and RC, plus: // atomic: Object class. Selection of the lvi will then show the object in the right pane. // seq/coll: Maybe size of vector. Selection shows basic list of items in the vector in the right pane. string data = "*N/A"; object obj = SilDataAccess.get_Prop(selObj.m_hvo, (int)flid); if (obj != null) { int flidType = MetaDataCache.GetFieldType(flid); switch (flidType) { case (int)CellarModuleDefns.kcptOwningCollection: case (int)CellarModuleDefns.kcptOwningSequence: case (int)CellarModuleDefns.kcptReferenceSequence: case (int)CellarModuleDefns.kcptReferenceCollection: string pfx = String.Empty; switch (flidType) { case (int)CellarModuleDefns.kcptOwningCollection: pfx = "OC"; break; case (int)CellarModuleDefns.kcptOwningSequence: pfx = "OS"; break; case (int)CellarModuleDefns.kcptReferenceSequence: pfx = "RS"; break; case (int)CellarModuleDefns.kcptReferenceCollection: pfx = "RC"; break; } int vecSize = m_cache.get_VecSize(selObj.m_hvo, (int)flid); List <int> hvos = (List <int>)m_cache.get_Prop(selObj.m_hvo, (int)flid); data = String.Format("{0}: {1} items", pfx, vecSize); lvi.Tag = new SelectedVector(selObj.m_hvo, flid, hvos); break; case (int)CellarModuleDefns.kcptInteger: if (flid == (int)CmObjectFields.kflidCmObject_Class) { classname = MetaDataCache.GetClassName(selObj.m_clid); data = String.Format("{0}: {1}", obj.ToString(), classname); } else { data = obj.ToString(); } break; case (int)CellarModuleDefns.kcptTime: DateTime dt = new DateTime((long)obj); data = dt.ToString(); break; case (int)CellarModuleDefns.kcptOwningAtom: // Fall through. case (int)CellarModuleDefns.kcptReferenceAtom: int objId = (int)obj; int clid = SilDataAccess.get_IntProp(objId, (int)CmObjectFields.kflidCmObject_Class); classname = MetaDataCache.GetClassName((uint)clid); data = String.Format("{0}: a(n) {1}", (flidType == (int)CellarModuleDefns.kcptOwningAtom) ? "OA" : "RA", classname); lvi.Tag = new SelectedObject(flid, objId, (uint)clid); break; case (int)CellarModuleDefns.kcptString: // Fall through. case (int)CellarModuleDefns.kcptBigString: ITsString tssString = (ITsString)obj; data = tssString.Text; break; case (int)CellarModuleDefns.kcptMultiUnicode: // Fall through. case (int)CellarModuleDefns.kcptMultiBigUnicode: // Fall through. case (int)CellarModuleDefns.kcptMultiString: // Fall through. case (int)CellarModuleDefns.kcptMultiBigString: if (obj is ITsMultiString) { ITsMultiString tsms = obj as ITsMultiString; uint wsLocalFlid = MetaDataCache.GetFieldId("LgWritingSystem", "ICULocale", false); if (tsms.StringCount > 0) { int ws; ITsString tss = tsms.GetStringFromIndex(0, out ws); string wsLabel = SilDataAccess.get_UnicodeProp(ws, (int)wsLocalFlid); data = String.Format("{0}: {1}", wsLabel, tss.Text); } lvi.Tag = tsms; } break; case (int)CellarModuleDefns.kcptUnicode: // Fall through. case (int)CellarModuleDefns.kcptBigUnicode: data = (string)obj; break; default: data = obj.ToString(); break; } } lvi.SubItems.Add(data); } } listView.Items.AddRange(list.ToArray()); listView.Sorting = SortOrder.Ascending; listView.Sort(); ResumeLayout(); }