2008-09-16 6 views
3

ListBox 패널의 높이 내에 더 이상 들어갈 수 없을 때 그룹이 오른쪽에서 왼쪽으로 줄 바꿈되는 그룹에서 항목을 표시하기 위해 ListBox를 만들었습니다.WPF ListBox WrapPanel 클립 긴 그룹

[ 1 ][ 3 ][ 5 ] 
[ ][ 4 ][ 6 ] 
[ 2 ][ ] 

다음 XAML은 그것이 제대로 작동 : 그래서, 그룹 각 그룹의 높이가 임의 목록 상자에서이 유사한 나타납니다 (그룹 1은, 예를 들어, 그룹 2 배 높이) 줄 바꿈을 수행하고 항목이 ListBox의 오른쪽에서 벗어날 때 가로 스크롤 막대가 표시되도록합니다.

<ListBox> 
    <ListBox.ItemsPanel> 
    <ItemsPanelTemplate> 
     <StackPanel Orientation="Vertical"/> 
    </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 

    <ListBox.GroupStyle> 
    <ItemsPanelTemplate> 
     <WrapPanel Orientation="Vertical" 
       Height="{Binding Path=ActualHeight, 
          RelativeSource={RelativeSource 
          FindAncestor, 
          AncestorLevel=1, 
          AncestorType={x:Type ScrollContentPresenter}}}"/> 
    </ItemsPanelTemplate> 
    </ListBox.GroupStyle> 
</ListBox> 

항목 그룹이 WrapPanel의 높이보다 긴 경우 문제가 발생합니다. 잘라 내기 항목 그룹을보기 위해 세로 스크롤 막대를 표시하는 대신 해당 그룹의 항목을 단순히 자릅니다. 나는 이것이 WrapPanel의 Height 바인딩의 부수적 인 효과라고 가정하고있다. 스크롤 바는 그것을 사용할 필요가 없다고 생각한다.

내가 볼 수없는이 문제를 해결하는 방법이 있습니까?

답변

0

저는 당신이 바인딩과 관련이 있다고 생각합니다. 바인딩을 제거하면 어떻게됩니까? 바인딩으로 적어도 목록 상자의 전체 높이를 채우려 고합니까? 그렇다면 대신 MinHeight에 바인딩하거나 VerticalAlignment 속성을 사용해보십시오.

0

응답 해 주셔서 감사합니다.

바인딩이 removed 인 경우 랩핑이 발생하지 않습니다. WrapPanel은 모든 그룹을 하나의 세로 열에 배치합니다.

바인딩은 WrapPanel을 실제로 감싸는 것을 의미합니다. 바인딩이 설정되어 있지 않으면 WrapPanel은 높이가 무한하며 랩핑하지 않는다고 가정합니다.

MinHeight에 바인딩하면 빈 목록 상자가 나타납니다. VerticalAlignment 속성이 어떻게 해결 될 수 있는지를 알 수 있지만 정렬 자체가 모든 래핑이 발생하는 것을 방지합니다. 바인딩과 정렬을 함께 사용하면 정렬이 문제에 영향을 미치지 않습니다.

2

WrapPanel의 Height 속성을 ScrollContentPresenter 높이로 설정하면 세로로 스크롤되지 않습니다. 레이아웃 패스에서 레이아웃에 무한한 높이가 있기 때문에 바인딩을 제거하면 결코 감싸지 않습니다.

원하는 동작을 얻으려면 자체 패널 클래스를 만드는 것이 좋습니다. 원하는 높이를 바인딩 할 수있는 별도의 종속성 속성이 있으므로이를 사용하여 측정에서 대상 높이를 계산하고 단계를 정렬 할 수 있습니다. 어느 아이가 원하는 높이보다 키가 큰 경우, 그 아이의 높이를 타겟 높이로 사용하여 줄 바꿈을 계산하십시오. 수평 및 수직 스크롤을 모두 할 수 있습니다 - - 이전에 게시 아베 Heidebrecht에 주어진 모든 신용

다음
public class SmartWrapPanel : WrapPanel 
{ 
    /// <summary> 
    /// Identifies the DesiredHeight dependency property 
    /// </summary> 
    public static readonly DependencyProperty DesiredHeightProperty = DependencyProperty.Register(
     "DesiredHeight", 
     typeof(double), 
     typeof(SmartWrapPanel), 
     new FrameworkPropertyMetadata(Double.NaN, 
      FrameworkPropertyMetadataOptions.AffectsArrange | 
      FrameworkPropertyMetadataOptions.AffectsMeasure)); 

    /// <summary> 
    /// Gets or sets the height to attempt to be. If any child is taller than this, will use the child's height. 
    /// </summary> 
    public double DesiredHeight 
    { 
     get { return (double)GetValue(DesiredHeightProperty); } 
     set { SetValue(DesiredHeightProperty, value); } 
    } 

    protected override Size MeasureOverride(Size constraint) 
    { 
     Size ret = base.MeasureOverride(constraint); 
     double h = ret.Height; 

     if (!Double.IsNaN(DesiredHeight)) 
     { 
      h = DesiredHeight; 
      foreach (UIElement child in Children) 
      { 
       if (child.DesiredSize.Height > h) 
        h = child.DesiredSize.Height; 
      } 
     } 

     return new Size(ret.Width, h); 
    } 

    protected override System.Windows.Size ArrangeOverride(Size finalSize) 
    { 
     double h = finalSize.Height; 

     if (!Double.IsNaN(DesiredHeight)) 
     { 
      h = DesiredHeight; 
      foreach (UIElement child in Children) 
      { 
       if (child.DesiredSize.Height > h) 
        h = child.DesiredSize.Height; 
      } 
     } 

     return base.ArrangeOverride(new Size(finalSize.Width, h)); 
    } 
} 
+0

이것은 거의 * 정확한 해결책입니다. 수직 스크롤링이 가능하지만 수평 스크롤링은 중지됩니다.약간 수정했는데 (다음 답변에 표시된 수정 된 코드) 완벽하게 작동합니다. 고마워, 아베. –

2

가 약간 수정 된 코드입니다 : 여기

이 작업을 수행하려면 예를 들어 패널입니다. 유일한 변화는 MeasureOverride의 반환 값이 base.MeasureOverride (new Size (ret.width, h)) 여야한다는 것입니다.

// Original code : Abe Heidebrecht 
public class SmartWrapPanel : WrapPanel 
{ 
    /// <summary> 
    /// Identifies the DesiredHeight dependency property 
    /// </summary> 
    public static readonly DependencyProperty DesiredHeightProperty = DependencyProperty.Register(
    "DesiredHeight", 
    typeof(double), 
    typeof(SmartWrapPanel), 
    new FrameworkPropertyMetadata(Double.NaN, 
      FrameworkPropertyMetadataOptions.AffectsArrange | 
      FrameworkPropertyMetadataOptions.AffectsMeasure)); 

    /// <summary> 
    /// Gets or sets the height to attempt to be. If any child is taller than this, will use the child's height. 
    /// </summary> 
    public double DesiredHeight 
    { 
    get { return (double)GetValue(DesiredHeightProperty); } 
    set { SetValue(DesiredHeightProperty, value); } 
    } 

    protected override Size MeasureOverride(Size constraint) 
    { 
    Size ret = base.MeasureOverride(constraint); 
    double h = ret.Height; 

    if (!Double.IsNaN(DesiredHeight)) 
    { 
     h = DesiredHeight; 
     foreach (UIElement child in Children) 
     { 
     if (child.DesiredSize.Height > h) 
      h = child.DesiredSize.Height; 
     } 
    } 

    return base.MeasureOverride(new Size(ret.Width, h)); 
    } 

    protected override System.Windows.Size ArrangeOverride(Size finalSize) 
    { 
    double h = finalSize.Height; 

    if (!Double.IsNaN(DesiredHeight)) 
    { 
     h = DesiredHeight; 
     foreach (UIElement child in Children) 
     { 
     if (child.DesiredSize.Height > h) 
      h = child.DesiredSize.Height; 
     } 
    } 

    return base.ArrangeOverride(new Size(finalSize.Width, h)); 
    } 
}