简体   繁体   中英

WPF project integrating a UWP Xaml Island GridView

I'm trying to use the GridView control from UWP inside my WPF project. My goal is to have horizontal scrolling container that has 3 rows, so a WPF ListView is not enough; also the performance is really bad on touch devices. Another thing is that I have experience with GridView from UWP and the control is beyond anything that WPF has to offer.

So I started with a Xaml Island using the WindowsXamlHost:

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. Is there any posibility to add ItemsSource inside the xaml declaration of the host? If I do add it, I'm getting that ItemsSource is not a member of XamlHost. This means that it is not recognized as a GridView.

  2. Because I couldn't add the ItemsSource in xaml, I did it in code:

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

This resolved the ItemsSource issue.

  1. But the big problem came when trying to add the data template. I tried a number of things but every outcome was that I could not add a WPF DataTemplate to the UPW GridView control.

My last attempt was to have a xaml file in the assets folder which would hold the DataTemplate, read it and create a UWP DataTemplate and pass it to the 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;
      }
  }

At this point the application was ready to build and run. The result is that the app starts, appears on the screen as it should be, then freezes and I'm getting the classic App does not respond.

Is there anyone that used a UWP GridView inside WPF? Is there a smarter solution to use DataTemplates in such a case?

Update: It seems that the issue comes from the DataTemplate. If I display a simple text as a DataTempalte it will show up. But I have some Binding to do inside that DataTemplate:

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

The app breaks when I reference MovieObject and try to bind it's properties. So how can I use an object to bind, inside a template.xaml file. Now the app breaks when hitting the x:DataType="MovieObject".

Is there any posibility to add ItemsSource inside the xaml declaration of the host?

No, you should set the ItemsSource of the instance of the type that gets created by the WindowsXamlHost programmatically like you are currently doing. The host itself has no ItemsSource property. Even if you get the instance from the Child property, you'll still have to cast it.

When it comes to the template definition, you could remove the x:DataType attribute and replace any compiled bindings ( x:Bind ) with regular dynamic {Binding} expressions:

<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 doesn't support the x:DataType attribute that is used for the sole purpose of being able to used compiled bindings that are validated at compile time in the template.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM