2008-09-16 11 views
3

ListBoxのパネルの高さに収まらなくなったときに、グループが右から左に折り返されたアイテムを表示するためにListBoxを作成しました。WPFリストボックス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

Davidにお返事ありがとうございます。

バインディングがremovedの場合、折り返しが発生しません。 WrapPanelは、すべてのグループを単一の垂直列に置きます。

バインドは、WrapPanelを実際に折り返すように強制することを意味します。バインディングが設定されていない場合、WrapPanelは高さが無限でラップしないとみなします。

MinHeightにバインドすると、空のリストボックスになります。私はVerticalAlignmentプロパティが解決策のように思えるかもしれないが、アラインメント自体はラッピングが発生するのを防ぐことができます。バインディングとアラインメントを併用すると、アライメントは問題に影響しません。

2

WrapPanelのHeightプロパティをScrollContentPresenterの高さに設定すると、垂直方向にスクロールしません。しかし、そのバインディングを削除すると、レイアウトパスではレイアウトに無限の高さがあるため、決して折り返されません。

あなたが望む動作を得るために、独自のパネルクラスを作成することをお勧めします。必要な高さをバインドできる別の依存関係プロパティがあるので、それを使用してメジャー内のターゲットの高さを計算し、ステップを配置することができます。いずれかの子が希望の高さよりも背が高い場合は、その高さを目標高さとしてラップを計算します。ここで

はこれを行うには例のパネルである:ここで

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

はわずかに変更されたコードです - 以前にそれを掲示安倍Heidebrechtに与えられたすべてのクレジット、 - 水平および垂直の両方のスクロールを可能にします。唯一の変更は、MeasureOverrideの戻り値がbase.MeasureOverride(新しいサイズ(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)); 
    } 
} 
関連する問題