拉伸/设置图块以适合 ListView

发布于 2024-10-13 20:21:13 字数 1919 浏览 4 评论 0 原文

我已经使用基于 http://msdn.microsoft 的代码实现了 ListView 的自定义视图.com/en-us/library/ms748859.aspx

在“TileView”中,我如何设置 ListView 来拉伸每个图块以适应可用空间。即,即使 ListView 更改大小,也可以在 ListView 中精确地容纳 3 列(即保持每个图块始终为 1/3 宽)

<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 个图块,并在该示例中更改以下 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 列:)

I've implemented custom view for ListView using code based on http://msdn.microsoft.com/en-us/library/ms748859.aspx

In the 'TileView" how would I set ListView to stretch each tile to fit the available space. I.e. fit exactly 3 columns in the ListView even if the ListView changes size (i.e. keep each tile always 1/3 wide).

<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>

Edit:

I have got the ListView to display x tiles using the above and changing the following XAML in that example:

  <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>

This is exactly what I need where if the ListView resizes the columns will resize as well.

Now I need to figure out how to change the UniformGrid Columns dynamically :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

江湖彼岸 2024-10-20 20:21:13

我对这个主题有两个考虑:

  1. 您的 DataTemplate 应适合所有排列的矩形。我的意思是 StackPanel 的属性 Height/Width = 100 不好。请改用带有比例行的 Grid 或 DockPanel。
  2. 没有可以满足您要求的标准面板。我认为您应该使用 ColumnCount 属性从 Panel(或 WrapPanel)类编写自己的继承者。然后重写 ArrangeOverride 和 MeasureOverride 方法并根据 ColumnCount 提供适当的矩形。

它正在工作演示,但您应该根据您的要求改进 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>

I have two consideration on subject:

  1. Your DataTemplate should fit to all arranged rectangle. I mean StackPanel with properties Height/Width = 100 is no good. Use Grid with proportional rows or DockPanel instead.
  2. There is no standart panel that fills your requirements. I think you should write your own inheritor from Panel(or WrapPanel) class with ColumnCount property. Then override ArrangeOverride and MeasureOverride methods and provide proper rectangles according to ColumnCount.

It's working demonstration but you should improve MyPanel according to your requirements:

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); 

    }
}

Usage in XAML:

   <ListView ItemsSource="{Binding Items}" 
              ItemTemplate="{StaticResource Template}"
              >
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <self:MyPanel ColumnCount="3"  />
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
    </ListView>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文