using System;
using System.Windows;
using System.Windows.Controls;

namespace CustomPanels
{
  public class SimpleStackPanel : Panel
  {
      // Kierunek układania
    public static readonly DependencyProperty OrientationProperty = 
      DependencyProperty.Register("Orientation", typeof(Orientation),
      typeof(SimpleStackPanel), new FrameworkPropertyMetadata(Orientation.Vertical,
      FrameworkPropertyMetadataOptions.AffectsMeasure));

    public Orientation Orientation
    {
      get { return (Orientation)GetValue(OrientationProperty); }
      set { SetValue(OrientationProperty, value); }
    }

    protected override Size MeasureOverride(Size availableSize)
    {
      Size desiredSize = new Size();

      // Niech elementy podrzędne rozrastają się w kierunku układania,
      // zastępując to, co zostało przekazane.
      if (Orientation == Orientation.Vertical)
        availableSize.Height = Double.PositiveInfinity;
      else
        availableSize.Width = Double.PositiveInfinity;

      foreach (UIElement child in this.Children)
      {
          if (child != null)
          {
              // Zapytaj pierwszy element podrzędny, jaki byłby jego docelowy
              // rozmiar, gdyby miał nieskończoną ilość miejsca w kierunku układania
              // i całą dostępną przestrzeń (jaka została przekazana) w drugim kierunku.
              child.Measure(availableSize);

              // Nasz pożądany rozmiar jest sumą rozmiarów elementów podrzędnych 
              // w kierunku układania oraz rozmiaru największego elementu
              // podrzędnego w kierunku przeciwnym.
              if (Orientation == Orientation.Vertical)
              {
                  desiredSize.Width = Math.Max(desiredSize.Width,
                                               child.DesiredSize.Width);
                  desiredSize.Height += child.DesiredSize.Height;
              }
              else
              {
                  desiredSize.Height = Math.Max(desiredSize.Height,
                                                child.DesiredSize.Height);
                  desiredSize.Width += child.DesiredSize.Width;
              }
          }
      }

      return desiredSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
      double offset = 0;

      foreach (UIElement child in this.Children)
      {
          if (child != null)
          {
              if (Orientation == Orientation.Vertical)
              {
                  // Parametr offset przesuwa element podrzędny o jedno piętro w dół.
                  // Oddaj elementowi podrzędnemu naszą całą szerokość, ale tylko tyle
                  // wysokości, ile potrzebuje. 
                  child.Arrange(new Rect(0, offset, finalSize.Width,
                                                    child.DesiredSize.Height));

                  // Zaktualizuj parametr offset dla kolejnego elementu podrzędnego.
                  offset += child.DesiredSize.Height;
              }
              else
              {
                  // Parametr offset przesuwa element podrzędny o jedno piętro w dół.
                  // Oddaj elementowi podrzędnemu naszą całą szerokość, ale tylko tyle
                  // wysokości, ile potrzebuje.
                  child.Arrange(new Rect(offset, 0, child.DesiredSize.Width,
                                                    finalSize.Height));

                  // Zaktualizuj parametr offset dla kolejnego elementu podrzędnego.
                  offset += child.DesiredSize.Width;
              }
          }
      }

      // Wypełnij całą przydzieloną przestrzeń.
      return finalSize;
    }
  }
}