/// <summary> /// This is used to return the property value for the specified property name /// </summary> /// <param name="item">The item from which to get the info</param> /// <param name="field">The field on which to get the info</param> /// <returns>The found property value or the item itself if not found</returns> protected object FilterItemOnProperty(object item, string field) { if(item != null && field != null && field.Length > 0) { try { PropertyDescriptor pd; if(dataManager != null) pd = dataManager.GetItemProperties().Find(field, true); else pd = TypeDescriptor.GetProperties(item).Find(field, true); if(pd != null) item = pd.GetValue(item); } catch(Exception ex) { // Should this really eat exceptions? The .NET ListControl class does. We'll log them for // debugging purposes for the time being. if(System.Diagnostics.Debugger.IsAttached) { // Can't use System.Diagnostics.Debug as it gets excluded from the release build. This // does the same thing though but is compiled into the release build. using(var dtl = new System.Diagnostics.DefaultTraceListener()) { dtl.WriteLine(LR.GetString("ExFilterItemOnProp", this.Name, ex.Message)); } } } } return item; }
/// <summary> /// This is used to create the rows and bind each one to a row in the data source /// </summary> private void BindData() { TemplateControl ctl; Separator sep; int idx, top = 0, sepTop = 0, sepWidth = pnlRows.Width; bool bindFailed = false; if(inBindData) return; Cursor oldCursor = this.Cursor; if(oldCursor != Cursors.WaitCursor) this.Cursor = Cursors.WaitCursor; inBindData = isBinding = true; try { pnlRows.Visible = false; pnlRows.SuspendLayout(); pnlRows.AutoScrollPosition = new Point(0, 0); RemoveRows(); this.Select(-1, -1, -1); // If we don't have both, there's nothing to do if(rowTemplate == null || listManager == null) return; // Bind the header and footer controls if(header != null) { header.SetRowSourceInternal(dataSource); header.Bind(); header.HasBeenBound = true; OnHeaderDataBound(new DataListEventArgs(-1, header)); } if(footer != null) { footer.SetRowSourceInternal(dataSource); footer.Bind(); footer.HasBeenBound = true; OnFooterDataBound(new DataListEventArgs(-1, footer)); } // Create the row template items ConstructorInfo ctor = rowTemplate.GetConstructor(Type.EmptyTypes); rowHeight = -1; for(idx = 0; idx < listManager.Count; idx++, top += rowHeight, sepTop += rowHeight) { ctl = (TemplateControl)ctor.Invoke(null); ctl.Enter += RowTemplate_Enter; ctl.TemplateParentInternal = this; if(rowHeight == -1) { ctl.InitializeTemplate(); ctl.HasBeenInitialized = true; sepTop = rowHeight = ctl.Height; if(showSep) rowHeight += sepHeight; if(ctl.Width > sepWidth) sepWidth = ctl.Width; } ctl.Location = new Point(0, top); pnlRows.Controls.Add(ctl); if(showSep) { sep = new Separator(sepColor, sepHeight, sepWidth, 0, sepTop); pnlRows.Controls.Add(sep); } // Set the control's row source ctl.SetRowSourceInternal(listManager.List[idx]); } } catch(Exception ex) { bindFailed = true; // Something in the data binding hierarchy tends to eat exceptions that occur during binding and // you never see them (i.e. bad field names in a binding). This logs them to the debugger if one // is attached. if(System.Diagnostics.Debugger.IsAttached) { // Can't use System.Diagnostics.Debug as it gets excluded from the release build. This does // the same thing though but is compiled into the release build. using(var dtl = new System.Diagnostics.DefaultTraceListener()) { dtl.WriteLine(LR.GetString("ExBindData1", this.Name, ex.Message)); } } } finally { this.CalculateGlyphPoints(); if(!bindFailed) if(!changePolicy.AllowAdditions) { this.Invalidate(new Rectangle(0, 0, rowHeaderWidth, this.Height), false); this.Update(); } else this.AddNewRowTemplate(); lblRowCount.Text = LR.GetString("DLNavRowCount", (listManager != null) ? listManager.Count : 0); if(oldCursor != Cursors.WaitCursor) this.Cursor = oldCursor; inBindData = false; // Problems with the bindings will manifest themselves here (i.e. bad field names, etc). try { pnlRows.ResumeLayout(); pnlRows.Visible = true; this.Invalidate(); this.Update(); } catch(Exception ex) { // As above. Log the exception so that we know it occurred. if(System.Diagnostics.Debugger.IsAttached) using(var dtl = new System.Diagnostics.DefaultTraceListener()) { dtl.WriteLine(LR.GetString("ExBindData2", this.Name, ex.Message)); } } finally { isBinding = false; } // Force the focus to the proper row currentRow = (dataSource == null) ? 0 : -1; DataSource_PositionChanged(this, EventArgs.Empty); if(listManager != null && listManager.Count == 0) OnNoRows(EventArgs.Empty); } }