/// <summary> /// Handle the <see cref="ZeroitPandaPanel.PropertyChange" /> event /// </summary> /// <param name="xpPanel">The <see cref="ZeroitPandaPanel" /> whose property changed</param> /// <param name="e">instance of <see cref="ZeroitPandaPanelPropertyChangeEventArgs" /> describing the property change</param> /// <remarks>Currently we handle the <see cref="ZeroitPandaPanelProperties.PanelHeightProperty" /> so that we can /// ensure that the entire panel is visible. The <see cref="ZeroitPandaPanelProperties.PanelHeightProperty" /> /// is only changed when a <see cref="ZeroitPandaPanel" /> resizes due to a change in the size of child /// controls. Typically this indicates some interest/focus on the users part, but you may want to /// supress this event if these changes are 'randomesque' in your application</remarks> private void ZeroitPandaPanelGroup_PropertyChange(ZeroitPandaPanel xpPanel, ZeroitPandaPanelPropertyChangeEventArgs e) { if (e.ZeroitPandaPanelProperty == ZeroitPandaPanelProperties.PanelHeightProperty) { EnsureVisible(xpPanel); } }
/// <summary> /// Update the location and width of all the <see cref="ZeroitPandaPanel" /> controls /// in the <see cref="ZeroitPandaPanelGroup" /> /// </summary> private void UpdatePanels() { int lastBottom = 0; if (isInitializingComponent || updatingPanels) { return; } updatingPanels = true; for (int i = 0; i < panels.Count; i++) { ZeroitPandaPanel panel = (ZeroitPandaPanel)panels[i]; if (!panel.Visible) { continue; } UpdatePanel(panel, lastBottom); lastBottom = panel.Top + panel.Height; } updatingPanels = false; }
/// <summary> /// Update an individual <see cref="ZeroitPandaPanel" /> /// </summary> /// <param name="panel">The panel to be updated</param> /// <param name="lastBottom">Bottom position of last <see cref="ZeroitPandaPanel" /> or 0 if this is the 1st panel /// in the <c>ZeroitPandaPanelGroup</c></param> private void UpdatePanel(ZeroitPandaPanel panel, int lastBottom) { if (panel.Left != BorderMargin.Width) { panel.Left = BorderMargin.Width; } if (lastBottom != 0) { if (panel.Top != lastBottom + PanelSpacing) { panel.Top = lastBottom + PanelSpacing; } } else { if (panel.Top != lastBottom + BorderMargin.Height) { panel.Top = lastBottom + BorderMargin.Height; } } if (panel.Width != this.Width - (BorderMargin.Width << 1) - (VScroll ? SystemInformation.VerticalScrollBarWidth : 0)) { panel.Width = this.Width - (BorderMargin.Width << 1) - (VScroll ? SystemInformation.VerticalScrollBarWidth : 0); } }
/// <summary> /// Change the order/position of the specified <see cref="ZeroitPandaPanel" /> /// </summary> /// <param name="newIndex">The new index/position</param> /// <param name="xpPanel">The <see cref="ZeroitPandaPanel" /> to move</param> public void MovePanel(int newIndex, ZeroitPandaPanel xpPanel) { int indexOf = panels.IndexOf(xpPanel); if ((indexOf != -1) && (indexOf != newIndex)) { panels.RemoveAt(indexOf); panels.Insert(newIndex, xpPanel); UpdatePanels(); } }
/// <summary> /// <see cref="ZeroitPandaPanel.PanelStateChange" /> event handler /// </summary> /// <param name="sender">The <see cref="ZeroitPandaPanel" /> that changed</param> /// <param name="e"><see cref="System.EventArgs.Empty" /></param> private void ZeroitPandaPanelGroup_PanelStateChange(object sender, EventArgs e) { ZeroitPandaPanel panel = sender as ZeroitPandaPanel; // sometimes this needs to be forced if (panel.Width != this.Width - (BorderMargin.Width << 1) - (VScroll ? SystemInformation.VerticalScrollBarWidth : 0)) { panel.Width = this.Width - (BorderMargin.Width << 1) - (VScroll ? SystemInformation.VerticalScrollBarWidth : 0); } UpdatePanelsAfter((ZeroitPandaPanel)sender); }
/// <summary> /// Set the height of the <c>ItemLayoutPanel</c> and if applicable, the height /// of parent <see cref="ZeroitPandaPanel" />'s panel area to match our height (with /// a little margin) /// </summary> /// <param name="bestHeight">The best height as determined by the layout engine</param> public virtual void SetBestHeight(int bestHeight) { this.Height = bestHeight; if (!DesignMode) { ZeroitPandaPanel panel = Parent as ZeroitPandaPanel; if (panel != null) { panel.PanelHeight = bestHeight + 12; } } }
/// <summary> /// Ensure that the specified panel is fully visible (if possible) within /// the <c>ZeroitPandaPanelGroup</c> /// </summary> /// <param name="xpPanel">The <see cref="ZeroitPandaPanel" /> to make visible</param> /// <exception cref="System.ArgumentException">The specified ZeroitPandaPanel is not a member of this ZeroitPandaPanelGroup - ZeroitPandaPanel</exception> /// <exception cref="ArgumentException">If the specified <see cref="ZeroitPandaPanel" /> is not /// a member of the <c>ZeroitPandaPanelGroup</c></exception> /// <remarks>If the panel is not visible it is made visible. If the bottom of the panel /// not visible, the group is scrolled to make it visible, otherwise if the /// top of the panel is not visible the scroll is adjusted to make it visible</remarks> public void EnsureVisible(ZeroitPandaPanel xpPanel) { if (!panels.Contains(xpPanel)) { throw new ArgumentException("The specified ZeroitPandaPanel is not a member of this ZeroitPandaPanelGroup", "ZeroitPandaPanel"); } if (!xpPanel.Visible) { xpPanel.Visible = true; } if (xpPanel.Bottom > (Height + AutoScrollPosition.Y)) { AutoScrollPosition = new Point(AutoScrollPosition.X, xpPanel.Bottom - Height); } else if (xpPanel.Top < 0) { AutoScrollPosition = new Point(AutoScrollPosition.X, Math.Max(0, xpPanel.Top - 1)); } }
/// <summary> /// Update the location of all the <see cref="ZeroitPandaPanel" /> controls /// in the <see cref="ZeroitPandaPanelGroup" /> after a particular index /// </summary> /// <param name="panel">The panel.</param> /// <remarks>Used when a panel is collapsed or expanded to change all the /// subsequent panels</remarks> private void UpdatePanelsAfter(ZeroitPandaPanel panel) { // @@BUGFIX: 1.1 if (!panel.Visible) { UpdatePanels(); return; } if (isInitializingComponent || updatingPanels) { return; } updatingPanels = true; // the bottom of the specified panel plus the BorderMargin.Height (which we always need // to take into account) int lastBottom = panel.Top + panel.Height; // map the panel to its index in our panels collection int panelIndex = panels.IndexOf(panel) + 1; // for each following panel, relocate it for (int i = panelIndex; i < panels.Count; i++) { ZeroitPandaPanel nextPanel = (ZeroitPandaPanel)panels[i]; // @@BUGFIX: 1.1 if (!nextPanel.Visible) { continue; } UpdatePanel(nextPanel, lastBottom); lastBottom = nextPanel.Top + nextPanel.Height; } updatingPanels = false; }
/// <summary> /// Convert to an <see cref="InstanceDescriptor" /> if requested /// </summary> /// <param name="context">designer context</param> /// <param name="culture">globalization</param> /// <param name="value">the instance to convert</param> /// <param name="destinationType">The target type</param> /// <returns>An <see cref="InstanceDescriptor" /> if requested, otherwise whatever /// the base class returns</returns> public override object ConvertTo( ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType ) { // the designer wants an InstanceDescriptor if ((destinationType == typeof(InstanceDescriptor)) && (value is ZeroitPandaPanel)) { ZeroitPandaPanel xpPanel = value as ZeroitPandaPanel; // Get our ZeroitPandaPanel(int) constructor ConstructorInfo ctorInfo = typeof(ZeroitPandaPanel).GetConstructor(new Type[] { typeof(int) }); if (ctorInfo != null) { // use this constructor and pass in the ExpandedHeight value. Use false to say that // initialization is NOT complete return(new InstanceDescriptor(ctorInfo, new object[] { xpPanel.ExpandedHeight }, false)); } } return(base.ConvertTo(context, culture, value, destinationType)); }