/// <summary> /// This method and its overloads can be used to simplify adding data bindings to controls contained in /// the template. /// </summary> /// <param name="control">The control to which to add the data binding</param> /// <param name="controlProperty">The name of the control property to bind</param> /// <param name="dataMember">The property or list to which to bind</param> /// <param name="clearBindings">Specify true to clear all existing bindings before adding the new binding /// or false to keep all existing bindings.</param> /// <param name="formatEvent">An event handler for the binding's <c>Format</c> event if wanted</param> /// <param name="parseEvent">An event handler for the binding's <c>Parse</c> event if wanted</param> /// <remarks>This version will only clear the existing data bindings if the <c>clearBindings</c> /// parameter is true. It will also add the specified format and parse event handlers to the binding if /// they are specified. Use null if you do not want a particular handler added.</remarks> /// <returns>The newly created data binding</returns> /// <exception cref="ArgumentNullException">This is thrown if the control parameter is null</exception> public Binding AddBinding(Control control, string controlProperty, string dataMember, bool clearBindings, ConvertEventHandler formatEvent, ConvertEventHandler parseEvent) { if (control == null) { throw new ArgumentNullException("control", LR.GetString("ExNullParameter")); } Binding b = new Binding(controlProperty, rowSource, dataMember); if (formatEvent != null) { b.Format += formatEvent; } if (parseEvent != null) { b.Parse += parseEvent; } if (clearBindings) { control.DataBindings.Clear(); } control.DataBindings.Add(b); return(b); }
/// <summary> /// Sets the check state of the item at the specified index to the specified value /// </summary> /// <param name="index">The index of the item to change</param> /// <param name="state">The new check state of the item</param> /// <exception cref="ArgumentOutOfRangeException">This is thrown if the index value is not within the /// bounds of the item collection.</exception> /// <overloads>There are two overloads for this method</overloads> public void SetItemCheckState(int index, CheckState state) { if (index < 0 || index >= this.Items.Count) { throw new ArgumentOutOfRangeException("index", index, LR.GetString("ExItemIndexOutOfRange")); } ((CheckBox)this.ButtonPanel.Controls[index]).CheckState = state; }
/// <summary> /// Returns a value indicating whether the specified item is checked /// </summary> /// <param name="index">The index of the item to examine</param> /// <returns>True if the item is checked, false if it is not</returns> /// <exception cref="ArgumentOutOfRangeException">This is thrown if the index value is not within the /// bounds of the item collection.</exception> /// <overloads>There are two overloads for this method</overloads> public bool GetItemChecked(int index) { if (index < 0 || index >= this.Items.Count) { throw new ArgumentOutOfRangeException("index", index, LR.GetString("ExItemIndexOutOfRange")); } return(((CheckBox)this.ButtonPanel.Controls[index]).Checked); }
/// <summary> /// Returns a value indicating the current check state of the item with the specified value /// </summary> /// <param name="key">The item in the data source to examine. The <see cref="BaseListControl.ValueMember"/> /// is searched for this value.</param> /// <returns>The current check state of the specified item</returns> /// <exception cref="ArgumentOutOfRangeException">This is thrown if the value is not found in the /// collection.</exception> public CheckState GetItemCheckState(object key) { int index = this.Find(key); if (index == -1) { throw new ArgumentOutOfRangeException("key", key, LR.GetString("ExItemIndexOutOfRange")); } return(((CheckBox)this.ButtonPanel.Controls[index]).CheckState); }
//===================================================================== /// <summary> /// This is called to force the control to refresh the checkboxes with information from the data source /// </summary> /// <exception cref="InvalidOperationException">This is thrown if a <see cref="BindingMembersDataSource"/> /// has been specified and there are more checkbox list items that members specified in /// <see cref="BindingMembers"/>.</exception> public override void RefreshSubControls() { Panel bp = this.ButtonPanel; Binding b; CheckBox cb; CheckState[] states; int idx = 0, imageIdx = 0, memberIdx = 0; ControlCollection cc = bp.Controls; states = new CheckState[cc.Count]; // Dispose of any prior checkboxes while (cc.Count > 0) { cb = (CheckBox)cc[0]; states[idx] = cb.CheckState; cb.Enter -= CheckBox_Enter; cb.CheckStateChanged -= CheckBox_CheckStateChanged; cc.RemoveAt(0); cb.Dispose(); idx++; } idx = 0; foreach (object oItem in this.Items) { cb = new CheckBox(); // In .NET 2.0, we could use the UseMnemonic property but it doesn't work with FlatStyle.System // so we'll modify the text which works with it and with .NET 1.1. if (this.UseMnemonic) { cb.Text = this.GetItemText(oItem).Replace("&&", "&"); } else { cb.Text = this.GetItemText(oItem).Replace("&", "&&"); } cb.Appearance = base.Appearance; cb.FlatStyle = this.FlatStyle; cb.ThreeState = threeState; cb.CheckAlign = base.CheckAlign; cb.TextAlign = base.TextAlign; cb.ImageAlign = base.ImageAlign; cb.ImageList = base.ImageList; // Don't hook up the event in design mode. They are clickable. We'll also skip hooking up the // data bindings. if (!this.DesignMode) { cb.Enter += CheckBox_Enter; cb.CheckStateChanged += CheckBox_CheckStateChanged; // If we have a data source and available members, bind the checkbox's CheckState to the // member. if (bindingDataSource != null) { if (memberIdx < bindingMembers.Count) { if (bindingContext != null) { cb.BindingContext = bindingContext; } b = new Binding("CheckState", bindingDataSource, bindingMembers[memberIdx]); b.Format += BindingMember_Format; b.Parse += BindingMember_Parse; cb.DataBindings.Add(b); memberIdx++; } else { throw new InvalidOperationException(LR.GetString("ExTooFewBindingMembers")); } } } if (base.ImageList != null) { cb.ImageIndex = imageIdx; imageIdx++; // Wrap the index if there are more items than images if (imageIdx == base.ImageList.Images.Count) { imageIdx = 0; } } // Restore the state if necessary if (this.SelectedIndex != -1 && idx < states.Length) { cb.CheckState = states[idx]; } bp.Controls.Add(cb); idx++; } base.RefreshSubControls(); this.PerformLayout(); }
/// <summary> /// This is used to bind controls to the row source. Derived controls must override this to provide data /// binding support even if they contain no bound controls. /// </summary> /// <remarks>This will not be called until the template is scrolled into view. This saves time and /// resources during the initial startup phase of a form that contains a data list control. Templates /// are re-bound under many conditions. If adding bindings to controls manually, be sure to clear the /// <c>DataBindings</c> collection on all bound controls first. A better alternative is to use the /// overloaded <see cref="AddBinding(Control, string, string)"/> method as it will take care of that for /// you.</remarks> /// <exception cref="NotImplementedException">This is thrown if the method is not overridden and the base /// implementation is called.</exception> /// <example> /// <code language="cs"> /// protected override void Bind() /// { /// this.AddBinding(txtFName, "Text", "FirstName"); /// this.AddBinding(txtLName, "Text", "LastName"); /// this.AddBinding(txtAddress, "Text", "Address"); /// this.AddBinding(txtCity, "Text", "City"); /// this.AddBinding(cboState, "SelectedValue", "State"); /// this.AddBinding(txtZip, "Text", "Zip"); /// this.AddBinding(udcSumValue, "Text", "SumValue"); /// } /// </code> /// <code language="vbnet"> /// Protected Overrides Sub Bind() /// Me.AddBinding(txtFName, "Text", "FirstName") /// Me.AddBinding(txtLName, "Text", "LastName") /// Me.AddBinding(txtAddress, "Text", "Address") /// Me.AddBinding(txtCity, "Text", "City") /// Me.AddBinding(cboState, "SelectedValue", "State") /// Me.AddBinding(txtZip, "Text", "Zip") /// Me.AddBinding(udcSumValue, "Text", "SumValue") /// End Sub /// </code> /// </example> protected internal virtual void Bind() { throw new NotImplementedException(LR.GetString("TCBindNotOverridden", this.GetType().Name)); }
/// <summary> /// Handle vertical scroll to make it smoother /// </summary> /// <remarks>The default scrolling increments are quite small and the frequent redraws cause a messy /// display when the thumb is dragged. By handling it ourselves, we can initialize and bind the rows /// before they are displayed and can also control the increments to provide a smoother scroll with a /// cleaner visual appearance.</remarks> /// <param name="m">The vertical scroll message parameters</param> private void HandleVerticalScroll(ref Message m) { TemplateControl tc; DataList owner = (DataList)this.Parent; Rectangle clientRect = base.ClientRectangle, displayRect = base.DisplayRectangle; int row, fillRange, maxRows, multiplier, rowHeight = owner.RowHeight, curPos = -displayRect.Y; int maxPos = -(clientRect.Height - displayRect.Height - rowHeight), scrollEvent = (int)m.WParam & 0xFFFF; switch (scrollEvent) { case 0: // Line up if (curPos <= 0) { curPos = 0; } else { curPos -= rowHeight; } break; case 1: // Line down if (curPos >= maxPos - rowHeight) { curPos = maxPos; } else { curPos += rowHeight; } break; case 2: // Page up if (curPos <= clientRect.Height) { curPos = 0; } else { curPos -= clientRect.Height; } break; case 3: // Page down if (curPos >= maxPos - clientRect.Height) { curPos = maxPos; } else { curPos += clientRect.Height; } break; case 4: // Thumb position (end tracking) case 5: // Thumb track (drag) if (scrollTip == null) { scrollTip = new NativeToolTipWindow(this); } // Round it to the nearest row start and show the position in a tool tip curPos = UnsafeNativeMethods.ScrollThumbPosition(base.Handle, 1) / rowHeight * rowHeight; scrollTip.ShowTooltip(String.Format(CultureInfo.InvariantCulture, LR.GetString("DLScrollPos"), (curPos / rowHeight) + 1, owner.RowCount)); break; case 6: // Top curPos = 0; break; case 7: // Bottom curPos = maxPos; break; case 8: // End scroll if (scrollTip != null && scrollTip.IsVisible) { scrollTip.HideTooltip(); } break; case 32767: // Custom call to scroll row into view curPos = m.LParam.ToInt32(); if (curPos < 0) { curPos = 0; } else if (curPos >= maxPos) { curPos = maxPos; } break; } // Ignore if not displaying content while scrolling and it was a thumb tracking event if (this.GetScrollState(0x10) || scrollEvent != 5) { // Initialize and bind the rows before they are displayed to smooth out the scrolling multiplier = (owner.SeparatorsVisible) ? 2 : 1; if (owner.ListManager != null && this.Controls.Count != 0) { maxRows = owner.ListManager.Count; // Get the range of visible rows row = curPos / rowHeight; fillRange = ((curPos + rowHeight + this.Height) / rowHeight) + 1; if (fillRange < maxRows) { maxRows = fillRange; } } else { row = maxRows = 0; } while (row < maxRows) { if (row * multiplier < this.Controls.Count) { tc = (TemplateControl)this.Controls[row * multiplier]; } else { tc = null; } // By waiting until the templates scroll into view, it saves some time and resources during // the initial load and only binds what is actually shown. if (tc != null && !tc.IsNewRowInternal && !tc.HasBeenBound) { if (!tc.HasBeenInitialized) { tc.InitializeTemplate(); tc.HasBeenInitialized = true; } tc.Bind(); tc.HasBeenBound = true; owner.OnItemDataBound(new DataListEventArgs(row, tc)); } row++; } // Set "user scrolled" flag and update the display rectangle this.SetScrollState(8, true); this.SetDisplayRectLocation(displayRect.X, -curPos); if (syncScrollbars != null) { syncScrollbars.Invoke(this, new object[] { this.AutoScroll }); } // Refresh the row headers if they are visible if (owner.RowHeadersVisible) { owner.Invalidate(new Rectangle(0, 0, owner.RowHeaderWidth, owner.Height), false); } } if (scrollEvent != 8) { ScrollEventArgs se = new ScrollEventArgs((ScrollEventType)scrollEvent, -displayRect.Y, curPos, ScrollOrientation.VerticalScroll); base.OnScroll(se); } }