How to get gridview with variable sized gridview items?

假装没事ソ 提交于 2019-12-01 10:43:35

问题


I want to show images in grouped gridview. Now all the images will have various height & width So I want to show images in it's original height width. I tried WrapGrid, VariableSizedWrapGrid & VirtualizingStackPanel but didn't get the output. Please note my model class contains image name (path), height & width. So how can I show images like given below ?


回答1:


No, I doubt you tried a WrapPanel. There's not one in WinRT.

Using VariableSizedWrapGrid you get a result something like this:

Using a WrapGrid you get a result something like this:

Presto! The trick?

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>

But there's one gotcha. I am not correctly setting the width of the WrapPanel. In the code above, I've defaulted it to 2000 (which is ridiculous). You'll have to figure that part out and post your solution here. (I can't do everything) Otherwise, it's what you are asking for 100%.

The WinRT WrapPanel is on my blog http://jerrynixon.com (on the left column)

Good luck, Farhan.

See also: ms forum where you asked the same thing




回答2:


Well, if this is the layout you want then you don't want a Grid View for the layout since it is not a grid. A GridView will size all its items based on the first item's size. You would most likely need a custom ItemsControl implementation for that layout.




回答3:


If you have options to use html/winjs for the application, you can try out list view item template sample scenario 4 - "Creating a templating function that can span multiple cells". Here you may opt for using smaller grid unit, and define multiple css classes. In the item template fn based on image size, use the best fit css class to scale the image.

for example:

.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;
}

you get the idea. more css classes with different aspect ratios can be defined. In this case, you need to use -ms-grid-row-align: center for one dimension and other dimension as 100% for the item to ensure image fits the cell and does not get distorted.

If you can not use winjs, then I see some samples which talk about variable grid size in GridView for c#. but I have not tried them out. These links might be helpful.

  • Variable size grouped gridview
  • Grid with variable size items


来源:https://stackoverflow.com/questions/16843050/how-to-get-gridview-with-variable-sized-gridview-items

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!