-1

我正在尝试在我的 WPF 项目中使用 UWP 中的 GridView 控件。我的目标是拥有 3 行的水平滚动容器,因此 WPF ListView 是不够的;触摸设备的性能也很差。另一件事是我有使用 UWP 的 GridView 的经验,并且该控件超出了 WPF 必须提供的任何东西。

所以我从使用 WindowsXamlHost 的 Xaml 岛开始:

xmlns:xamlhost="clr-namespace:Microsoft.Toolkit.Wpf.UI.XamlHost;assembly=Microsoft.Toolkit.Wpf.UI.XamlHost"

<xamlhost:WindowsXamlHost InitialTypeName="Windows.UI.Xaml.Controls.GridView"
          x:Name="MainGrid"
          HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
          ChildChanged="MainGrid_ChildChanged">
</xamlhost:WindowsXamlHost>
  1. 是否有可能在主机的 xaml 声明中添加 ItemsSource?如果我添加它,我会得到 ItemsSource 不是 XamlHost 的成员。这意味着它不被识别为 GridView。

  2. 因为我无法在 xaml 中添加 ItemsSource,所以我在代码中完成了:

    private void MainGrid_ChildChanged(object sender, EventArgs e)
    {
        WindowsXamlHost windowsXamlHost = (WindowsXamlHost)sender;
    
        Windows.UI.Xaml.Controls.GridView gridView =
            (Windows.UI.Xaml.Controls.GridView)windowsXamlHost.Child;
    
        if (gridView != null)
        {
            MainGridView = gridView;
            MainGridView.ItemsSource = Items;
        }
    }
    

这解决了 ItemsSource 问题。

  1. 但是在尝试添加数据模板时出现了大问题。我尝试了很多事情,但每个结果都是我无法将 WPF DataTemplate 添加到 UPW GridView 控件。

我最后一次尝试是在 assets 文件夹中有一个 xaml 文件,该文件将保存 DataTemplate,读取它并创建一个 UWP DataTemplate 并将其传递给 GridView。

private void testDataTemplate()
{
     using (Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(path))
     {
          StreamReader reader = new StreamReader(stream);
          string text = reader.ReadToEnd();
          object root = Windows.UI.Xaml.Markup.XamlReader.Load(text) as Windows.UI.Xaml.DataTemplate;
          Windows.UI.Xaml.DataTemplate temp = root as Windows.UI.Xaml.DataTemplate;

          // pass the Data Template to the UWP GridView - temp is valid
          MainGridView.ItemTemplate = temp;
      }
  }

此时,应用程序已准备好构建和运行。结果是应用程序启动,按原样出现在屏幕上,然后冻结,我得到经典应用程序没有响应。

有没有人在 WPF 中使用过 UWP GridView?在这种情况下是否有更智能的解决方案来使用 DataTemplates?

更新:似乎问题来自 DataTemplate。如果我将一个简单的文本显示为 DataTempalte,它将显示出来。但是我在那个 DataTemplate 中有一些绑定要做:

<DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
              x:DataType="MovieObject">
    <Grid Width="254" Height="160" Margin="0" Padding="0">

当我引用 MovieObject 并尝试绑定它的属性时,应用程序会中断。那么如何在 template.xaml 文件中使用对象进行绑定。现在应用程序在点击 x:DataType="MovieObject" 时会中断。

4

1 回答 1

0

是否有可能在主机的 xaml 声明中添加 ItemsSource?

不,您应该设置ItemsSource由编程方式创建的类型的实例,WindowsXamlHost就像您当前正在做的那样。主机本身没有ItemsSource财产。即使您从Child属性中获取实例,您仍然必须强制转换它。

当涉及到模板定义时,您可以删除该x:DataType属性并将任何已编译的绑定 ( x:Bind) 替换为正则动态{Binding}表达式:

<DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <Grid Width="254" Height="160" Margin="0" Padding="0">
        <TextBlock Text="{Binding SomePropertyOfMovieObject}" />
    </Grid>
</DataTemplate>

XamlReader.Load不支持x:DataType仅用于能够使用在模板中的编译时验证的已编译绑定的属性。

于 2020-05-12T15:21:47.673 回答