2008-09-16 2 views
3

Я создал ListBox для отображения элементов в группах, где группы обернуты справа налево, когда они больше не могут вписываться в высоту панели ListBox. Таким образом, группы будут выглядеть подобно этому в ListBox, где высота каждой группы произвольно (группа 1, например, в два раза выше группы 2):WPF ListBox WrapPanel клипы длинные группы

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

Следующая XAML правильно работает в этом ему выполняет обертку и позволяет горизонтальной полосе прокрутки появляться, когда элементы работают с правой стороны 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. Вместо того, чтобы позволить вертикальной полосе прокрутки появляться для просмотра группы элементов отсечки, элементы в этой группе просто обрезаются. Я предполагаю, что это побочный эффект привязки Height в WrapPanel - полоса прокрутки думает, что ее не нужно активировать.

Есть ли способ включить панель прокрутки или по-другому вокруг этой проблемы, которую я не вижу?

ответ

0

Я думаю, что вы правы, что это связано с привязкой. Что происходит, когда вы удаляете привязку? С привязкой вы пытаетесь заполнить хотя бы всю высоту списка? Если это так, рассмотрите возможность привязки к MinHeight или попробуйте использовать свойство VerticalAlignment.

0

Благодарим за ответ, Дэвид.

Когда привязка removed, обертывания не происходит. WrapPanel помещает каждую группу в один вертикальный столбец.

Связывание предназначено для принудительного переноса WrapPanel. Если привязка не установлена, WrapPanel предполагает, что высота бесконечна и никогда не обертывается.

Привязка к MinHeight приводит к пустому списку. Я вижу, как свойство VerticalAlignment может показаться решением, но само выравнивание предотвращает появление какой-либо обертки. Когда привязка и выравнивание используются вместе, выравнивание не влияет на проблему.

2

Установив свойство Height на WrapPanel на высоту 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

Это * почти * точное решение, в котором я нуждаюсь. Он позволяет выполнять вертикальную прокрутку, но останавливать горизонтальную прокрутку.Я немного изменил его (измененный код, показанный в следующем ответе), и он отлично работает. Спасибо, Эйб. – 2008-09-17 12:42:30

2

Вот немного измененный код - весь кредит дается Abe Гейдебрехт, который ранее разместил его - что позволяет как горизонтальную и вертикальную прокрутку. Единственное изменение заключается в том, что возвращаемое значение 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)); 
    } 
} 
Смежные вопросы