【问题标题】:How to get gridview with variable sized gridview items?如何获得具有可变大小的gridview项目的gridview?
【发布时间】:2013-06-08 14:08:39
【问题描述】:

我想在分组的网格视图中显示图像。现在所有图像都有不同的高度和宽度所以我想以原始高度宽度显示图像。我尝试了WrapGridVariableSizedWrapGridVirtualizingStackPanel,但没有得到输出。请注意我的模型类包含图像名称(路径)、高度和宽度。那么如何显示如下所示的图像?

【问题讨论】:

  • 好的,我已将所有代码添加到我的答案中。

标签: gridview windows-8 windows-store-apps winrt-xaml


【解决方案1】:

不,我怀疑您尝试过 WrapPanel。 WinRT 中没有。

使用 VariableSizedWrapGrid 你会得到类似这样的结果:

使用 WrapGrid 你会得到类似这样的结果:

快!诀窍?

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }
}

public class MyViewModel
{
    public MyViewModel()
    {
        var _Random = new Random((int)DateTime.Now.Ticks);
        var _Colors = typeof(Windows.UI.Colors)
            // using System.Reflection;
            .GetRuntimeProperties()
            .Select((c, i) => new
            {
                Title = c.Name,
                Color = (Windows.UI.Color)c.GetValue(null),
                ColSpan = _Random.Next(20, 300),
                RowSpan = _Random.Next(20, 300),
            });
        this.Groups = new System.Collections.ObjectModel.ObservableCollection<object>();
        this.Groups.Add(new { Title = "Mostly Red", Children = _Colors.Where(x => x.Color.R > 200) });
        this.Groups.Add(new { Title = "Mostly Green", Children = _Colors.Where(x => x.Color.G > 200) });
        this.Groups.Add(new { Title = "Mostly Blue", Children = _Colors.Where(x => x.Color.B > 200) });
    }
    public System.Collections.ObjectModel.ObservableCollection<object> Groups { get; private set; }
}

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">

    <Grid.DataContext>
        <local:MyViewModel />
    </Grid.DataContext>

    <Grid.Resources>
        <CollectionViewSource 
            x:Name="MyCsv"
            IsSourceGrouped="True"
            ItemsPath="Children"
            Source="{Binding Groups}"
            d:Source="{Binding Groups, Source={d:DesignInstance Type=local:MyViewModel, IsDesignTimeCreatable=True}}" />
    </Grid.Resources>

    <GridView ItemsSource="{Binding Source={StaticResource MyCsv}}">
        <GridView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Rectangle Height="20" Width="20" Fill="{Binding Brush}" Margin="0,0,10,0" />
                            <TextBlock FontSize="40" Text="{Binding Title}" />
                        </StackPanel>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
                <GroupStyle.Panel>
                    <ItemsPanelTemplate>
                        <local:WrapPanel Orientation="Vertical" Width="2000" />
                        <!--<VariableSizedWrapGrid Margin="0,0,80,0" ItemHeight="1" ItemWidth="1" />-->
                    </ItemsPanelTemplate>
                </GroupStyle.Panel>
            </GroupStyle>
        </GridView.GroupStyle>
        <GridView.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" Margin="0,0,80,0" />
            </ItemsPanelTemplate>
        </GridView.ItemsPanel>
        <GridView.ItemTemplate>
            <DataTemplate>
                <Grid Height="{Binding RowSpan}" Width="{Binding ColSpan}">
                    <Grid.Background>
                        <SolidColorBrush Color="{Binding Color}" />
                    </Grid.Background>
                </Grid>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>

</Grid>

但有一个问题。我没有正确设置 WrapPanel 的宽度。在上面的代码中,我将其默认为 2000(这很荒谬)。您必须弄清楚那部分并在此处发布您的解决方案。 (我不能做所有事情)否则,这就是你要求的 100%。

WinRT WrapPanel 在我的博客http://jerrynixon.com(在左栏)

祝你好运,法尔汉。

另见:ms forum where you asked the same thing

【讨论】:

  • 嗨,我已经发布了有问题的代码(更新 2),它不起作用,它只是显示空白屏幕。
  • 太好了,终于成功了。我的错误是在CollectionViewSource 绑定休息是正确的。现在我必须考虑如何确定WrapPanel 的宽度。我很高兴收到你的建议,杰瑞。
  • +1 是一个不错的解决方案。您可以使用正确的WrapPanel implementation 来解决WrapPanelWidth 问题。
  • 在没有固定高度或宽度的情况下,这真是一项艰巨的工作。最后,我将宽度设置为可绑定的值(在我的情况下固定为窗口大小),并通过每次完成一行时添加最大数值来计算高度。然后我设置 CustomWrapPanel 的 Height 属性。为了防止不必要的高度更新,我检查了仅在高度属性实际不同时才更新它。我希望这在某个时候对某人有所帮助:)
【解决方案2】:

好吧,如果这是您想要的布局,那么您不想要该布局的 Grid 视图,因为它不是网格。 GridView 将根据第一个项目的大小调整其所有项目的大小。您很可能需要该布局的自定义 ItemsControl 实现。

【讨论】:

  • 是的,但仍然需要WrapPanel
【解决方案3】:

如果您可以选择为应用程序使用 html/winjs,您可以尝试list view item template sample 场景 4 -“创建可以跨越多个单元格的模板函数”。在这里您可以选择使用较小的网格单元,并定义多个 css 类。在基于图片大小的item模板fn中,使用最适合的css类对图片进行缩放。

例如:

.square-image
{
    width: 200px;
    height: 200px;
}

// 4:3 aspect ratio
.landscape-image
{
    width: 200px;
    height: 150px;
}

// aspect ratio 4:6
portrait-image
{
    width: 200px;
    height: 300px;
}

你明白了。可以定义更多具有不同纵横比的 CSS 类。在这种情况下,您需要将-ms-grid-row-align: center 用于一个维度,将另一个维度作为100% 用于项目,以确保图像适合单元格并且不会失真。

如果您不能使用 winjs,那么我会看到一些示例,这些示例在 C# 的 GridView 中讨论可变网格大小。但我还没有尝试过。这些链接可能会有所帮助。

【讨论】:

  • 感谢您的回答,但它是 XAML/C# 项目,而不是 HTML/WinJS
  • 对于 xaml,您可以尝试答案中的链接以防万一。
  • 所有示例都是基于行跨度和列跨度我要设置高度和宽度。
猜你喜欢
  • 2012-04-05
  • 2014-02-16
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-28
  • 2011-10-02
相关资源
最近更新 更多