TemplateSelector для UWP FlipView

Я создал приложение Xamarin.Forms UWP, и мне казалось, что у вас на ногах ведро с цементом, когда вы пытаетесь пересечь Средиземное море вплавь. Поэтому я переключился на нативное программирование UWP.

Мое приложение создается на 95% динамически. Все элементы управления страницами на страницах зависят от того, что сохранено в базе данных.

У меня есть одна страница входа, carouselPage (FlipView) и QuitPage.

Все остальные страницы загружаются динамически и добавляются в FlipView-ItemsSource.

В Xamarin у меня был TemplateSelector, подобный тому, что указан в этой ссылке: https://github.com/alexrainman/CarouselView/blob/master/Demo/Views/MyTemplateSelector.cs

Мой вопрос: как я могу динамически создавать DateTemplates из моих представлений/страниц?

Кстати: я переключился с Xamarin на родной из-за серьезных проблем с производительностью. Карусель каждый раз переключается на первый элемент, и ей требуется несколько секунд, чтобы снова отобразить «настоящую» страницу после изменения размера (через виртуальную клавиатуру).

Я надеюсь на решение без таких проблем с производительностью, когда в списке более 30 элементов.

Может быть, кто-нибудь может объяснить, почему существует такая проблема с производительностью? Я не могу поверить, что каждая страница будет перезагружена из-за размера, измененного виртуальным килобайтом.

Спасибо всем заранее.

РЕДАКТИРОВАТЬ:

После того, как я нашел кнопку для редактирования, вот что у меня получилось:

У меня есть страница с именем CarouselView. В Xaml у меня есть FlipView с именем «myCarousel».

В CodeBehind у меня есть следующий код:

public partial class WellcomeView : BasePage {
#region Fields + Properties
private int _position;
public int Position { get { return _position; } set { _position = value; } }
#endregion

public CarouselView() {
    InitializeComponent();
    myCarousel.ItemTemplateSelector = new MyTemplateSelector();
    DataContext = new WellcomeViewModel(null, null, null, null, null);
}

public class MyTemplateSelector : Windows.UI.Xaml.Controls.DataTemplateSelector {
    private DataTemplate GreetingTemplate;
            ...

    public MyTemplateSelector() {
        this.GreetingTemplate = (DataTemplate)Windows.UI.Xaml.Markup.XamlReader.Load(new GreetingView().Content.ToString());
        ...
        // Here it throws an error. No matter if MainPage (with content) or other Views (with Content==null). But in every case I get a XamlParseException.
    } // End Ctor

    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) {
        var TemplateType = item.GetType();
        switch (TemplateType.Name) {
            case "GreetingViewModel":
            return base.SelectTemplateCore(GreetingTemplate );

            default:
            return base.SelectTemplateCore(BegruessungTemplate);
        } // End switch-case
    } // End SelectTemplateCore()
} // End MyTemplateSelector()

} // Конец класса WellcomeView

Вот ошибка, которую я получаю...

А вот и StackTrace:

at Windows.UI.Xaml.Markup.XamlReader.Load(String xaml)
   at MEDePORT_Win_Native.Views.WellcomeView.MyTemplateSelector..ctor()
   at MEDePORT_Win_Native.Views.WellcomeView..ctor()
   at MEDePORT_Win_Native.MEDePORT_Win_Native_XamlTypeInfo.XamlTypeInfoProvider.Activate_11_WellcomeView()
   at MEDePORT_Win_Native.MEDePORT_Win_Native_XamlTypeInfo.XamlUserType.ActivateInstance()
   at Windows.UI.Xaml.Controls.Frame.Navigate(Type sourcePageType, Object parameter)
   at MEDePORT_Win_Native.App.OnLaunched(LaunchActivatedEventArgs e)

РЕДАКТИРОВАТЬ: с "new MyView().Content.ToString()" я получаю только имя типа. Например, «Windows.Ui.Xaml.Controls.Grid».

Итак, похоже, мне нужно извлечь xaml из представления и преобразовать его в строку.

РЕДАКТИРОВАТЬ РЕДАКТИРОВАТЬ РЕДАКТИРОВАТЬ РЕДАКТИРОВАТЬ РЕДАКТИРОВАТЬ:

Каков эквивалент UWP для следующего кода?

 DataTemplate template = new DataTemplate { DataType = typeof(< Type of the object the template refers>) };

person Eden Cerberus    schedule 08.08.2017    source источник
comment
UWP также имеет DataTemplateSelector.   -  person Scavenger    schedule 09.08.2017
comment
@Scavenger Да, это правда, но я не нашел для себя никакого функционального решения. Я видел что-то подобное в Интернете: private DataTemplate FilmTemplate; public MyTemplateSelector() { this.FilmTemplate = (DataTemplate)XamlReader.Load(new FilmView().Content.ToString()); } Но я получаю NullReferences для каждой страницы/ContentView, кроме MainPage. Кажется, что контент из Xaml не был загружен, но я не понимаю, почему. Если я смогу отредактировать свой вступительный пост, я добавлю свое текущее решение для лучшего понимания. Спасибо.   -  person Eden Cerberus    schedule 09.08.2017
comment
Вы должны иметь возможность редактировать свой вопрос. Пожалуйста, добавьте код в свой вопрос, и минимально воспроизводимый пример может оказаться более полезным.   -  person Scavenger    schedule 09.08.2017
comment
@Scavenger Я добавил код выше. Моя единственная проблема заключается в том, что я не могу преобразовать содержимое страницы/представления в DataTemplate, потому что единственный доступный XamlReader не может этого сделать, и я не знаю, где взять другой упомянутый в Интернете. Мне нужно что-то вроде этого здесь: DataTemplate template = new DataTemplate { DataType = typeof(‹ Тип объекта, на который ссылается шаблон›) }; (Источник: stackoverflow.com/questions/5471405/)   -  person Eden Cerberus    schedule 18.08.2017
comment
Я отредактировал свой первоначальный вопрос. См. выше.   -  person Eden Cerberus    schedule 18.08.2017


Ответы (1)


Старайтесь создавать свои шаблоны не как xaml-файлы. Просто скопируйте содержимое шаблона в xaml-DataTemplate в новом файле Resources.Xaml.

Затем создайте свой TemplateSelector следующим образом:

public class MyTemplateSelector : DataTemplateSelector {
            public DataTemplate GreetingTemplate;
            static ResourceDictionary dataTemplates;

            public MyTemplateSelector() {
                if (dataTemplates == null) {
                    dataTemplates = new Templates.DataTemplates();
                }

                GreetingTemplate = dataTemplates["GreetingTemplate"] as DataTemplate; // Look how to load Your Templates!
            }

И верните свои шаблоны следующим образом:

защищенное переопределение DataTemplate SelectTemplateCore (элемент объекта, контейнер DependencyObject) { var TemplateType = item.GetType();

        switch (TemplateType.Name) {
            case "GreetingViewModel":
                return GreetingTemplate;

            default:
                return base.SelectTemplateCore(GreetingTemplate);
        }
    }

Класс Templates.DataTemplates() из первого примера кода выглядит так:

public partial class DataTemplates : ResourceDictionary {
        public DataTemplates() {
            InitializeComponent();
        }
    }

и его xaml содержит ваши DataTemplates.

Надеюсь это поможет.

person Deus Vult    schedule 25.08.2017