Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I prefer to use a DockedExpander class I wrote a while back (the code is included below). This class automatically sets itself up for whatever side of a DockPanel it is docked on.</p> <p>For example, in:</p> <pre><code>&lt;DockPanel&gt; &lt;edf:DockedExpander DockPanel.Dock="Left"&gt; &lt;ListBox ... &lt;/edf:DockedExpander&gt; &lt;Grid ... &lt;/DockPanel&gt; </code></pre> <p>The expander will open from the left, with the button facing the right way. But changing it to:</p> <pre><code> &lt;edf:DockedExpander DockPanel.Dock="Right"&gt; </code></pre> <p>will automatically adjust the rest of the expander to match. Same with "Top" and "Bottom" docking.</p> <p>I implemented DockedExpander because the thought of copying several hundred lines of WPF's internal code into my project was abhorrent to me. Also, my DockedExpander control automatically adapts to new theme styles because it reads WPF's internal styles.</p> <p>Here is the code for the DockedExpander class:</p> <pre><code>public class DockedExpander : Expander { static DockedExpander() { _directions = new Dictionary&lt;Dock, DirectionData&gt;(); _directions[Dock.Left] = new DirectionData { Reverse = Dock.Right, ExpandDirection = ExpandDirection.Right }; _directions[Dock.Right] = new DirectionData { Reverse = Dock.Left, ExpandDirection = ExpandDirection.Left }; _directions[Dock.Top] = new DirectionData { Reverse = Dock.Bottom, ExpandDirection = ExpandDirection.Down }; _directions[Dock.Bottom] = new DirectionData { Reverse = Dock.Top, ExpandDirection = ExpandDirection.Up }; DockPanel.DockProperty.OverrideMetadata(typeof(DockedExpander), new FrameworkPropertyMetadata { PropertyChangedCallback = (obj, e) =&gt; ((DockedExpander)obj).UpdateExpandDirection() }); ExpandDirectionProperty.OverrideMetadata(typeof(DockedExpander), new FrameworkPropertyMetadata { PropertyChangedCallback = (obj, e) =&gt; { throw new ArgumentException("Cannot set ExpandDirection because DockedExpander always computes its ExpandDirection from the DockPanel.Dock property"); } }); } public override void OnApplyTemplate() { base.OnApplyTemplate(); UpdateExpandDirection(); } private void UpdateExpandDirection() { // Can't use GetTemplateChild because non-PART_ names are not guaranteed to stay the same var dockPanel = FindTwoElementDockPanelUnder(this); var headerSite = dockPanel.Children[0]; var expandSite = dockPanel.Children[1]; // Compute the docking Dock myDock = DockPanel.GetDock(this); DirectionData myDockData = _directions[myDock]; DockPanel.SetDock(headerSite, myDockData.Reverse); DockPanel.SetDock(expandSite, myDock); headerSite.SetValue(FrameworkElement.StyleProperty, myDockData.HeaderSiteStyle); } private static Dictionary&lt;Dock, DirectionData&gt; _directions; private class DirectionData { public Dock Reverse; public ExpandDirection ExpandDirection; public Style HeaderSiteStyle { get { if(_headerSiteStyle==null) { var expander = new Expander { ExpandDirection = this.ExpandDirection }; expander.BeginInit(); expander.EndInit(); expander.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); var headerSite = FindTwoElementDockPanelUnder(expander).Children[0]; _headerSiteStyle = ((FrameworkElement)headerSite).Style; } return _headerSiteStyle; } } private Style _headerSiteStyle; } private static DockPanel FindTwoElementDockPanelUnder(DependencyObject visual) { while(true) switch(VisualTreeHelper.GetChildrenCount(visual)) { case 1: visual = VisualTreeHelper.GetChild(visual, 0); continue; case 2: return visual as DockPanel; default: return null; } } } </code></pre> <p>As usual, you need a namespace declaration (xmlns) in your XAML to be able to use a custom control.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload