拉伸/设置切片以适合ListView

时间:2011-01-23 10:22:30

标签: wpf xaml listview datatemplate

我使用基于http://msdn.microsoft.com/en-us/library/ms748859.aspx

的代码为ListView实现了自定义视图

在'TileView'中,我如何设置ListView来拉伸每个图块以适应可用空间。即使ListView改变大小(即保持每个图块总是1/3宽),也恰好在ListView中适合3列。 / p>

<l:PlainView x:Key="tileView" ItemTemplate="{StaticResource centralTile}" />

<DataTemplate x:Key="centralTile">
  <StackPanel>
    <Grid HorizontalAlignment="Center">
      <Image Source="{Binding XPath=@Image}" />
    </Grid>
    <TextBlock Text="{Binding XPath=@Name}" />
    <TextBlock Text="{Binding XPath=@Type}" />
  </StackPanel>
</DataTemplate>

编辑:

我已经使用上面的ListView显示x个tile并在该示例中更改了以下XAML:

  <Setter Property="ItemsPanel">
    <Setter.Value>
      <ItemsPanelTemplate>
        <WrapPanel Width="{Binding (FrameworkElement.ActualWidth),
                   RelativeSource={RelativeSource 
                                   AncestorType=ScrollContentPresenter}}"
                   ItemWidth="{Binding (ListView.View).ItemWidth,
                   RelativeSource={RelativeSource AncestorType=ListView}}"
                   MinWidth="{Binding (ListView.View).ItemWidth,
                   RelativeSource={RelativeSource AncestorType=ListView}}"
                   ItemHeight="{Binding (ListView.View).ItemHeight,
                   RelativeSource={RelativeSource AncestorType=ListView}}"/>
      </ItemsPanelTemplate>
    </Setter.Value>
  </Setter>
  <Setter Property="ItemsPanel">
    <Setter.Value>
      <ItemsPanelTemplate>
        <UniformGrid Columns="3"/>
      </ItemsPanelTemplate>
    </Setter.Value>
  </Setter>

这正是我所需要的,如果ListView调整大小,列也将调整大小。

现在我需要弄清楚如何动态更改UniformGrid列:)

1 个答案:

答案 0 :(得分:0)

我对主题有两点考虑:

  1. 您的DataTemplate应适合所有排列的矩形。我的意思是具有属性Height / Width = 100的StackPanel是不好的。请使用带比例行的网格或DockPanel。
  2. 没有标准面板满足您的要求。我认为你应该使用ColumnCount属性从Panel(或WrapPanel)类编写自己的继承者。然后重写ArrangeOverride和MeasureOverride方法,并根据ColumnCount提供正确的矩形。
  3. 这是工作演示,但你应该根据你的要求改进MyPanel:

    public class MyPanel : WrapPanel
    {
        public int ColumnCount
        {
            get 
            { 
                return (int)GetValue(ColumnCountProperty); 
            }
            set 
            {
                SetValue(ColumnCountProperty, value); 
            }
        }
    
        public static readonly DependencyProperty ColumnCountProperty =
            DependencyProperty.Register("ColumnCount", 
                typeof(int), 
                typeof(MyPanel), 
                new FrameworkPropertyMetadata(
                    0, 
                    FrameworkPropertyMetadataOptions.AffectsRender));
    
        protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize)
        {
            if (this.InternalChildren.Count == 0)
            {
                return finalSize;
            }
    
            var arrangedWidth = this.ActualWidth;
            var width = this.ActualWidth / this.ColumnCount;
            var x = 0.0; 
            var y = 0.0;
            var columnCounter = 0;
            for(int i = 0; i<this.InternalChildren.Count; i++)
            {
                if (columnCounter == this.ColumnCount)
                {
                    y += width;
                    x = 0;
                    columnCounter = 0;
                }
    
                columnCounter++;
                var ch = this.InternalChildren[i];
                ch.Arrange(new Rect(x, y, width, width));
                x = x + width;
            }
    
            return finalSize; 
        }
    
        protected override System.Windows.Size MeasureOverride(System.Windows.Size constraint)
        {
            if (this.InternalChildren.Count == 0)
            {
                return this.DesiredSize;
            }
    
            var supposedSize = base.MeasureOverride(constraint);
            var width = this.ActualWidth / this.ColumnCount;
            var rowsCount = this.InternalChildren.Count / this.ColumnCount + (this.InternalChildren.Count % this.ColumnCount > 0 ? 1 : 0);
            for (int i = 0; i < this.InternalChildren.Count; i++)
            {
                var ch = this.InternalChildren[i];
                ch.Measure(new Size(width, width));
    
            }
            double totalWidth = this.InternalChildren[0].DesiredSize.Width * this.ColumnCount;
            return new Size(totalWidth, rowsCount * width); 
    
        }
    }
    

    XAML中的用法:

       <ListView ItemsSource="{Binding Items}" 
                  ItemTemplate="{StaticResource Template}"
                  >
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <self:MyPanel ColumnCount="3"  />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
        </ListView>