Проект WPF, интегрирующий UWP Xaml Island GridView

Я пытаюсь использовать элемент управления GridView из UWP внутри своего проекта WPF. Моя цель - иметь контейнер с горизонтальной прокруткой с 3 строками, поэтому WPF ListView недостаточно; Кроме того, производительность на сенсорных устройствах очень плохая. Другое дело, что у меня есть опыт работы с GridView из UWP, а управление выходит за рамки всего, что может предложить WPF.

Итак, я начал с Xaml Island, используя 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. Есть ли возможность добавить ItemsSource в объявление xaml хоста? Если я добавлю его, я получу, что ItemsSource не является членом XamlHost. Это означает, что он не распознается как GridView.

  2. Поскольку я не мог добавить ItemsSource в xaml, я сделал это в коде:

    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.

Моя последняя попытка заключалась в том, чтобы иметь файл 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;
      }
  }

На этом этапе приложение было готово к сборке и запуску. В результате приложение запускается, появляется на экране, как должно быть, затем зависает, и я получаю, что классическое приложение не отвечает.

Есть ли кто-нибудь, кто использовал UWP GridView внутри WPF? Есть ли более разумное решение для использования 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".

1 ответ

Есть ли возможность добавить ItemsSource в объявление xaml хоста?

Нет, вы должны установить 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 Атрибут, который используется с единственной целью - иметь возможность использовать скомпилированные привязки, которые проверяются во время компиляции в шаблоне.

Другие вопросы по тегам