如何在运行时在垂直可滚动页面内动态创建水平可滚动 Gridview

Posted

技术标签:

【中文标题】如何在运行时在垂直可滚动页面内动态创建水平可滚动 Gridview【英文标题】:How to dynamically create horizontal scrollable Gridview inside verticallly scollable page at Runtime 【发布时间】:2017-06-02 05:37:08 【问题描述】:

我想创建一个像 android playstore 这样的页面,在其中我必须在运行时根据数据创建多个水平滚动的 Gridview。由于我是 Windows Phone 开发的新手,我不知道如何动态创建它。所以请提供任何类型的帮助或教程。

我已经用这个代码实现了下面的代码,我能够产生所需的结果,但是 gridview 项目 没有水平堆叠。我想让 项目水平滚动 所以请提供任何可以达到所需结果的帮助。我附上截图以供参考。

 public void DesignUi()
        
            GridViewItem grdItem = new GridViewItem();
            for (int i = 0; i < 20; i++)
            
                string backgroundColor = string.Empty;


                StackPanel staParent = new StackPanel();

                #region Header
                StackPanel headerStack = new StackPanel(); 

                headerStack.Background = new SolidColorBrush(Colors.Pink);
                TextBlock textHeader = new TextBlock();

                textHeader.Text = "Header  :-" + i;

                headerStack.Children.Add(textHeader);
                #endregion

                #region Body
                StackPanel staBody = new StackPanel(); 
                staBody.Background = new SolidColorBrush(Colors.Green);

                #region Create Grid View
                GridView grd = new GridView();
                grd.SetValue(ScrollViewer.VerticalScrollModeProperty, ScrollMode.Disabled);
                grd.SetValue(ScrollViewer.HorizontalScrollModeProperty, ScrollMode.Enabled);

                ItemsPanelTemplate itmPanel = new ItemsPanelTemplate();
                VirtualizingStackPanel vrStack = new VirtualizingStackPanel();
                vrStack.Orientation = Orientation.Horizontal;
                TextBlock textQ = new TextBlock();
                textQ.Text = "";
                vrStack.Children.Add(textQ);

                itmPanel.SetValue(VirtualizingStackPanel.IsVirtualizingProperty, true);

                itmPanel.SetValue(VirtualizingStackPanel.OrientationProperty, Orientation.Horizontal);
                itmPanel.SetValue(ItemsControl.ItemContainerStyleProperty, Orientation.Horizontal);
                ItemsControl itmCntrl = new ItemsControl();
                itmCntrl.Items.Add(vrStack);

                #region Create Gridview Items
                for (int j = 0; j < 4; j++)
                
                    grdItem = new GridViewItem();
                    grdItem.Width = 100;
                    grdItem.Height = 150;
                    grdItem.Margin = new Thickness(5, 5, 5, 5);
                    grdItem.Background = new SolidColorBrush(Colors.Red);
                    TextBlock textGrd = new TextBlock();
                    textGrd.Text = "Item :-" + j;
                    grdItem.Content = textGrd;
                    grd.Items.Add(grdItem);
                
                #endregion

                #endregion

                staBody.Children.Add(grd);
                #endregion

                staParent.Children.Add(headerStack);
                staParent.Children.Add(staBody);

                staLists.Children.Add(staParent);
            
        

Current Result Screenshot with the above code:--- Required Result Screenshot

【问题讨论】:

【参考方案1】:

我不得不将此作为答案,因为评论部分对此限制太多。所以我最好回答这个问题并指导你正确的方法


好的!有更好的方法来做到这一点。最好和最简单的方法是通过 DataBinding。它将您的代码减少到几乎没有,并且您在 XAML 中设计 GridView 比通过 c# 更容易。如果您不熟悉数据绑定的概念并且您想以您现在的方式实现它,那么我将添加到您的解决方案中,通过设置 @ 的 ItemsWrapGrid.Orientation 属性,GridView 将水平堆叠将 987654323@ 设置为垂直以水平堆叠元素,并记住将滚动模式也设置为水平。

对于滚动模式:将以下内容添加到您的 GridView XAML

ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollMode="Enabled" ScrollViewer.VerticalScrollMode="Disabled"

用于设置 ItemsWrapGrid 方向属性:

string template =
                "<ItemsPanelTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"><ItemsWrapGrid VerticalAlignment = \"Top\" "
                + " ItemWidth = \""
                + itemWidth
                + "\" Orientation = \"Vertical\"/></ItemsPanelTemplate> ";
yourgridview.ItemsPanel = (ItemsPanelTemplate)XamlReader.Load(template);

请注意: 实现这一点的更好更简洁的方法是通过 DataBinding,下面是通过 DataBinding 实现这一点的代码:

XAML

<GridView Name="ViewView" HorizontalAlignment="Center" ItemTemplate="StaticResource AllAppsTileData" IsItemClickEnabled="True" SelectionMode="Single" Margin="10" ItemsSource="Binding AppsToShow" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollMode="Enabled" ScrollViewer.VerticalScrollMode="Disabled">
                                <GridView.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <ItemsWrapGrid Orientation="Vertical"/>  <--Change this to Horizontal for vertically wrapping the items-->
                                    </ItemsPanelTemplate>
                                </GridView.ItemsPanel>
                                <GridView.ItemContainerStyle>
                                    <Style TargetType="GridViewItem">
                                        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                                        <Setter Property="Margin" Value="5"/>
                                    </Style>
                                </GridView.ItemContainerStyle>
                            </GridView>

数据模板 在你的&lt;Page.Resources&gt;中定义

<DataTemplate x:Key="AllAppsTileData">
        <Grid>
            <Grid.Background>
                <ImageBrush Stretch="Fill" ImageSource="Binding AppImage"/>
            </Grid.Background>
            <Grid>
                <Grid.Background>
                    <SolidColorBrush Color="Black" Opacity="0.3"/>
                </Grid.Background>
                <TextBlock Text="Binding AppName" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Grid>
        </Grid>
    </DataTemplate>

您的支持应用类

public class AppDataClass

    public string AppName  get; set; 

    public string AppImage  get; set;  //The image would be something like ms-appx:///Assets/LOGO.png


现在你已经准备好你的架构,你可以从这里开始,有两种方法,

    您将bindGridViewItemsSource 属性更改为ObservableCollection&lt;AppDataClass&gt;,可以使用MVVM 方法和每次ObservableCollection&lt;AppDataClass&gt; 更改时由您后面的代码或最好是ViewModel 填充,它会从接口INotifyPropertyChanged 引发RasiePropertyChanged 事件,并且视图会自动更新自身。这是一种强烈推荐的方法,因为它将您的 UI 和业务逻辑保持在两个不同的线程上,并且它们中的任何一个都不会相互交互,它们将通过 ViewModel 获取数据,这是 MVVM 方法以获取更多信息在上面使用This article

    正如您所解释的那样,您是电话开发的新手,我想说忘记第一点,因为如果您是该平台的新手,可能很难掌握,我推荐的是简单的方法, 从您后面的代码中将数据放入类似这样的列表中,

    List<AppDataClass> MyEntireData = new List<AppDataClass>(); MyEntireData = GetData(); GetData 方法向您返回 List&lt;AppDataClass&gt;,现在只是在 MyEntireData 不为空或计数大于 0 使用后,ViewView.ItemsSource = MyEntireData; 而且您将拥有更有条理的代码,为您提供商店方式的布局。

而且以后如果你想改变 Tiles 的外观,你不需要把头换成 c# 生成的 XAML,你只需要修改 DataTemplate

如果有任何事情请在 cmets 部分告诉我。

【讨论】:

以上是关于如何在运行时在垂直可滚动页面内动态创建水平可滚动 Gridview的主要内容,如果未能解决你的问题,请参考以下文章

jQuery-ui 可拖动滚动仅垂直

在 Uitableviewcontroller 内创建水平可滚动区域

WKWebView 可水平滚动

如何启用垂直滚动的滚动条并禁用水平滚动?

如何在 Android 中创建可滚动的轮播页面?

水平和垂直可滚动的大表格