2010-08-07 3 views
8

StackPanelReverseOrder 속성으로 빌드하고 싶습니다. StackPanel의 요소가 정상의 반대 순서 (예 : 맨 아래 오른쪽 또는 오른쪽)로 표시되게하려면 선언적으로 true로 설정할 수 있습니다 왼쪽으로). 즉석에서 뒤집을 수 있어야합니다.WPF에서 되돌릴 수있는 StackPanel 만들기

StackPanel에서 새 클래스를 파생시킬 생각이지만, 재정의 할 메소드를 알아야합니다.

최종 솔루션 :

protected override System.Windows.Size ArrangeOverride(System.Windows.Size arrangeSize) { 
    double x = 0; 
    double y = 0; 

    IEnumerable<UIElement> children = ReverseOrder ? InternalChildren.Cast<UIElement>().Reverse<UIElement>() : InternalChildren.Cast<UIElement>(); 
    foreach (UIElement child in children) { 
     var size = child.DesiredSize; 
     child.Arrange(new Rect(new Point(x, y), size)); 

     if (Orientation == Orientation.Horizontal) 
      x += size.Width; 
     else 
      y += size.Height; 
    } 

    if (Orientation == Orientation.Horizontal) 
     return new Size(x, arrangeSize.Height); 
    else 
     return new Size(arrangeSize.Width, y); 
} 

이 또한 정의하고 ReverseOrder를 등록하고 변경하는 경우 UpdateLayout를 호출합니다.

답변

12

FrameworkElement.ArrangeOverride를 다시 구현하고 모든 child.Arrange를 필요한 경우 평소보다 역순으로 호출 할 수 있습니다. (하지 테스트)이 같은

http://msdn.microsoft.com/en-us/library/system.windows.uielement.arrange.aspx

뭔가 :

double x = 0; 
    double y = 0; 

    var children = ReverseOrder ? InternalChildren.Reverse() : InternalChildren; 
    foreach (UIElement child in children) 
    { 
     var size = child.DesiredSize; 
     child.Arrange(new Rect(new Point(x, y), size)); 

     if (Orientation == Horizontal) 
      x += size.Width; 
     else 
      y += size.Height; 
    } 

당신이 ReverseOrder 속성을 변경 한 후에 UpdateLayout 호출해야합니다.

+0

완벽! 고마워요. 나는 그걸 생각할 필요조차 없었습니다! ;) – devios1

+1

uielements를 되 돌리는 효과는 무엇입니까? 실제로 ArrangeOverride에서 이전에 Apposed로 발생한 일이 무엇입니까? –

3

MeasureOverride

ArrangeOverride 사실, 당신의 측정 로직은 StackPanel에 동일 할 수있다, 그래서 당신은 단지 한 ArrangeOverride를 오버라이드 (override) 할 수 있습니다. StackPanel에는 직접 작성하는 경우 복제해야 할 수도있는 스크롤을 처리하는 논리가 있습니다. Panel에서 직접 상속 받아 스크롤을 지원하지 않을 수도 있습니다.

패널의 MSDN 페이지 또는 WPF Tutorial - Creating A Custom Panel Control 또는 Creating Custom Panels In WPF과 같은 사용자 지정 패널 작성에 대한 다양한 블로그 항목에서 Custom Panel Elements을 참조하십시오.

0

다른 변형입니다. StackPanelreference source을 기반으로하며 항목 정렬을 처리 할 수도 있습니다.

public class ReversibleStackPanel : StackPanel 
{ 
    public bool ReverseOrder 
    { 
     get => (bool)GetValue(ReverseOrderProperty); 
     set => SetValue(ReverseOrderProperty, value); 
    } 

    public static readonly DependencyProperty ReverseOrderProperty = 
     DependencyProperty.Register(nameof(ReverseOrder), typeof(bool), typeof(ReversibleStackPanel), new PropertyMetadata(false)); 


    protected override Size ArrangeOverride(Size arrangeSize) 
    { 
     bool fHorizontal = (Orientation == Orientation.Horizontal); 
     var rcChild = new Rect(arrangeSize); 
     double previousChildSize = 0.0; 

     var children = ReverseOrder ? InternalChildren.Cast<UIElement>().Reverse() : InternalChildren.Cast<UIElement>(); 
     foreach (UIElement child in children) 
     { 
      if (child == null) 
       continue; 

      if (fHorizontal) 
      { 
       rcChild.X += previousChildSize; 
       previousChildSize = child.DesiredSize.Width; 
       rcChild.Width = previousChildSize; 
       rcChild.Height = Math.Max(arrangeSize.Height, child.DesiredSize.Height); 
      } 
      else 
      { 
       rcChild.Y += previousChildSize; 
       previousChildSize = child.DesiredSize.Height; 
       rcChild.Height = previousChildSize; 
       rcChild.Width = Math.Max(arrangeSize.Width, child.DesiredSize.Width); 
      } 

      child.Arrange(rcChild); 
     } 

     return arrangeSize; 
    } 
}