Windows UWP - 如何将 GridView 包装在 HubSection 中

Posted

技术标签:

【中文标题】Windows UWP - 如何将 GridView 包装在 HubSection 中【英文标题】:Windows UWP - How to wrap GridView inside a HubSection 【发布时间】:2016-08-22 10:10:09 【问题描述】:

我有一个工作 GridView 的示例,但似乎无法将其移动到 HubSection 内工作。我真正的应用程序需要这样做,这个例子是我了解数据绑定需要如何工作的骡子。

HubSection 抱怨它不能有一个 GridView 作为一个孩子。

我当前的模型代码如下所示:

namespace Quickstart 
  public class Recording 
    public string ArtistName  get; set; 
    public string CompositionName  get; set; 
    public DateTime ReleaseDateTime  get; set; 
    public Uri ImageUri  get; set; 

    public Recording(string name, string composition, DateTime when, string prefixedFilename)
    
        this.ArtistName = name;
        this.CompositionName = composition;
        this.ReleaseDateTime = when;
     //   string prefixedFilename = "ms-appx://Quickstart/Assets/" + filename;
        ImageUri = new Uri(prefixedFilename);
    

    public string OneLineSummary 
        get
        
            return $"this.CompositionName by this.ArtistName, released: "
                + this.ReleaseDateTime.ToString("d");
        
    
  

  public class RecordingViewModel 
    List<Recording> recordings;

    public RecordingViewModel()
    
        recordings = new List<Quickstart.Recording>();
        recordings.Add(new Recording("Wolfgang Amadeus Mozart", "Andante in C for Piano", new DateTime(1761, 1, 1), "http://csimg.koopkeus.nl/srv/NL/29023839m56849/T/340x340/C/FFFFFF/url/mozart.jpg"));
        recordings.Add(new Recording("Nickleback", "Gotta be Somebody", new DateTime(2003, 8, 21), "http://images4.fanpop.com/image/photos/16500000/n-nickelback-16579001-634-634.jpg"));
    

    public List<Recording> RecordingList  get  return this.recordings;  
  


和 xaml:

<Page
x:Class="Quickstart.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Quickstart"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<GridView ItemsSource="x:Bind recordings" Background="ThemeResource ApplicationPageBackgroundThemeBrush" x:Name="RecordingGrid">
  <GridView.ItemTemplate>
        <DataTemplate x:DataType="local:Recording">
            <StackPanel>
                <Image Source="Binding ImageUri, Mode=TwoWay" Height="100" Opacity="1" Stretch="Uniform"/>
                <TextBlock Text="x:Bind ArtistName"/>
                <TextBlock Text="x:Bind CompositionName"/>
                <TextBlock Text="x:Bind ReleaseDateTime"/>
            </StackPanel>
        </DataTemplate>
    </GridView.ItemTemplate>
  </GridView>
</Page>

最后是 xaml.cs:

namespace Quickstart 
  public sealed partial class MainPage : Page 
    List<Recording> recordings;
    public MainPage() 
        this.InitializeComponent();
        recordings = new RecordingViewModel().RecordingList;
    
  

如您所见,它非常简单!谢谢你的时间!

【问题讨论】:

到底是什么问题?我什至没有在您的代码中看到 HubSection。 请在中心部分发布代码。您还需要将 GridView 放入 GridHubSection 【参考方案1】:

HubSection 抱怨它不能将 GridView 作为一个孩子。

这个问题可以参考HubSection class。对于 hub 部分,我们不直接向其添加内容,我们在 DataTemplate 中定义 HubSection 的内容。

所以对于你的问题,你可以这样做:

<Page.DataContext>
    <local:RecordingViewModel x:Name="vm" />
</Page.DataContext>

<Grid Background="ThemeResource ApplicationPageBackgroundThemeBrush">
    <Hub>
        <HubSection x:Name="section1" Width="600">
            <DataTemplate>
                <Grid>
                    <GridView ItemsSource="Binding recordings"  Background="ThemeResource ApplicationPageBackgroundThemeBrush" x:Name="RecordingGrid">
                        <GridView.ItemTemplate>
                            <DataTemplate>
                                <StackPanel>
                                    <Image Source="Binding ImageUri, Mode=TwoWay" Height="100" Opacity="1" Stretch="Uniform" />
                                    <TextBlock Text="Binding ArtistName" />
                                    <TextBlock Text="Binding CompositionName" />
                                    <TextBlock Text="Binding ReleaseDateTime" />
                                </StackPanel>
                            </DataTemplate>
                        </GridView.ItemTemplate>
                    </GridView>
                </Grid>
            </DataTemplate>
        </HubSection>
    </Hub>
</Grid>

执行此操作时(在 Xaml 中添加 DataContext),无需在 MainPage.cs 文件中添加任何代码:

//private List<Recording> recordings;

public MainPage()

    this.InitializeComponent();
    //recordings = new RecordingViewModel().RecordingList;

您需要像这样更改您的 RecordingViewModel 类:

public class RecordingViewModel

    public List<Recording> recordings
    
        get; set;
    

    public RecordingViewModel()
    
        recordings = new List<Recording>();
        recordings.Add(new Recording("Wolfgang Amadeus Mozart", "Andante in C for Piano", new DateTime(1761, 1, 1), "http://csimg.koopkeus.nl/srv/NL/29023839m56849/T/340x340/C/FFFFFF/url/mozart.jpg"));
        recordings.Add(new Recording("Nickleback", "Gotta be Somebody", new DateTime(2003, 8, 21), "http://images4.fanpop.com/image/photos/16500000/n-nickelback-16579001-634-634.jpg"));
    

    public List<Recording> RecordingList  get  return this.recordings;  

如您所知,如果您想在 DataTemplate 中使用 x:Bind,您应该定义 x:DataType 进行绑定,因为 x:Bind 的 Path 的值不会在页面的上下文,但在被模板化的数据对象的上下文中。

正如我们在这里看到的,GridView 已经在DataTemplate 中,因为只有一个数据上下文(你的 RecordingViewModel),但没有这个DataTemplate 的数据模型,我们不能使用 x:Bind 这里是 ItemSourceGridView 里面的。但是我们可以对GridViewDataTemplate里面的控件使用x:Bind,比如这样:

<Page.Resources>
    <DataTemplate x:DataType="local:Recording" x:Key="recordingitem">
        <StackPanel>
            <Image Source="Binding ImageUri, Mode=TwoWay" Height="100" Opacity="1" Stretch="Uniform" />
            <TextBlock Text="x:Bind ArtistName" />
            <TextBlock Text="x:Bind CompositionName" />
            <TextBlock Text="x:Bind ReleaseDateTime" />
        </StackPanel>
    </DataTemplate>
</Page.Resources>
<Page.DataContext>
    <local:RecordingViewModel x:Name="vm" />
</Page.DataContext>

<Grid Background="ThemeResource ApplicationPageBackgroundThemeBrush">
    <Hub>
        <HubSection x:Name="section1" Width="600">
            <DataTemplate>
                <Grid>
                    <GridView ItemsSource="Binding recordings" ItemTemplate="StaticResource recordingitem"  Background="ThemeResource ApplicationPageBackgroundThemeBrush" x:Name="RecordingGrid">
                    </GridView>
                </Grid>
            </DataTemplate>
        </HubSection>
    </Hub>
</Grid>

而且后面的代码和上面的Binding方法一样。

【讨论】:

非常感谢@Grace Feng 的全面而有用的回答!

以上是关于Windows UWP - 如何将 GridView 包装在 HubSection 中的主要内容,如果未能解决你的问题,请参考以下文章

Windows UWP - 如何将 GridView 包装在 HubSection 中

如何将 UWP 目标添加到现有 Xamarin Forms 项目?

如何在 UWP(通用 Windows 编程)应用程序中进行简单的用户登录

如何在 Windows 10 UWP 中实现图表控件

如何在 Windows 10 和 XBOX One UWP 应用之间使用漫游设置

如何分发UWP Enterprise应用程序