Frage

Der XAML-Code unten funktioniert gut, außer ich die Expander-Taste wird zwischen dem Listenfeld und dem Gitter will. Wenn stelle ich die ExpandDirection = „links“ die Taste zwischen der Listbox und dem Gitter, aber die Fahrtrichtungsanzeiger auf die Schaltfläche ist verwirrend für Benutzer - nach rechts zeigen, wenn erweitert und es zeigt auf der linken Seite, wenn es nicht erweitert wird. Ich mag, dass der Fahrtrichtungsanzeiger, wie es funktioniert arbeiten, wenn ExpandDirection = „Right“, aber ich mag die Funktionalität von ExpandDirection = „left“.

<DockPanel>
    <Expander ExpandDirection="Right">
        <ListBox>
            <ListBoxItem>Item One</ListBoxItem>
            <ListBoxItem>Item Two</ListBoxItem>
            <ListBoxItem>Item Three</ListBoxItem>
            <ListBoxItem>Item Four</ListBoxItem>
            <ListBoxItem>Item Five</ListBoxItem>
        </ListBox>
    </Expander>
        <Grid Background="AliceBlue">
          <TextBlock >
            Other Content
          </TextBlock>
        </Grid>
</DockPanel>
War es hilfreich?

Lösung

Mit Expression Blend, bearbeiten Sie eine Kopie der aktuellen Vorlage für den Expander, für die Vorlage zu XAML gehen, umbenennen „ExpanderLeftHeaderStyle“ auf „ExpanderRightHeaderStyle“ und „ExpanderRightHeaderStyle“ auf „ExpanderLeftHeaderStyle“.

Andere Tipps

Ich ziehe eine DockedExpander Klasse verwende ich eine Weile zurück schrieb (der Code unten enthalten). Diese Klasse stellt sich automatisch auf irgendwelchen Seite eines DockPanel es dockt auf.

Zum Beispiel in:

<DockPanel>
  <edf:DockedExpander DockPanel.Dock="Left">
    <ListBox ...
  </edf:DockedExpander>

  <Grid ...

</DockPanel>

Der Expander wird von der linken Seite öffnen, mit der Taste den richtigen Weg weist. Aber Ändern Sie es an:

  <edf:DockedExpander DockPanel.Dock="Right">

automatisch den Rest des Expanders einstellen zu lassen. Das Gleiche gilt für "Top" und "Bottom" Andocken.

I umgesetzt DockedExpander weil der Gedanke an das Kopieren von mehreren hundert Zeilen internen Code WPF in mein Projekt verabscheuungswürdig für mich war. Auch meine DockedExpander Steuerung passt sich automatisch an neue Designstile, weil es WPF internen Stile liest.

Hier ist der Code für die DockedExpander Klasse:

public class DockedExpander : Expander
{
  static DockedExpander()
  {
    _directions = new Dictionary<Dock, DirectionData>();
    _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) => ((DockedExpander)obj).UpdateExpandDirection()
    });

    ExpandDirectionProperty.OverrideMetadata(typeof(DockedExpander), new FrameworkPropertyMetadata
    {
      PropertyChangedCallback = (obj, e) => { 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<Dock, DirectionData> _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;
      }
  }
}

Wie üblich, benötigen Sie eine Namespace-Deklaration (xmlns) in XAML Lage sein, eine individuelle Steuerung zu verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top