Поделиться через


Перенос проектов Windows Phone Silverlight в проекты UWP

Предыдущий раздел был о пространстве имен и сопоставлении классов.

Процесс переноса начинается путем создания проекта Windows 10 в Visual Studio и копирования файлов в него.

Создание проекта и копирование файлов в него

  1. Запустите Microsoft Visual Studio 2015 и создайте новый проект пустого приложения (универсальное приложение Windows). Дополнительные сведения см. в статье Запуск приложения на платформе Windows Runtime 8.x с помощью шаблонов (C#, C++, Visual Basic). Новый проект создает пакет приложения (appx-файл), который будет выполняться во всех семействах устройств.
  2. В проекте приложения Windows Phone Silverlight определите все файлы исходного кода и файлы визуальных активов, которые требуется повторно использовать. Используя Проводник, скопируйте модели данных, модели представлений, визуальные ресурсы, словари ресурсов, структуру папок и другие элементы, которые вы хотите повторно использовать, в новый проект. При необходимости скопируйте или создайте вложенные папки на диске.
  3. Скопируйте файлы представления (например, MainPage.xaml и MainPage.xaml.cs) в новый элемент проекта. При необходимости создайте новые вложенные папки и удалите существующие представления из проекта. Но перед перезаписью или удалением представления, созданного Visual Studio, сохраните копию, так как она может оказаться полезной для ссылки на нее позже. Первый этап переноса приложения Windows Phone Silverlight фокусируется на том, чтобы он хорошо выглядел и эффективно функционировал на одном семействе устройств. Позже вы обратите внимание на то, чтобы представления хорошо адаптировались ко всем форм-факторам, при необходимости добавляя адаптивный код, чтобы максимально использовать возможности определенного семейства устройств.
  4. В обозревателе решенийубедитесь, что Показать все файлы включено. Выберите скопированные файлы, щелкните их правой кнопкой мыши и щелкните Включить в проект. Это будет автоматически включать их содержащиеся папки. После этого можно отключить показать все файлы, если вы хотите. Альтернативный рабочий процесс, если вы предпочитаете, заключается в использовании команды добавить существующий элемент, предварительно создав все необходимые вложенные папки в Visual Studio Solution Explorer . Дважды убедитесь, что для ваших визуальных ресурсов в параметре Действие сборки установлено значение Содержимое и в параметре Копировать в выходной каталог выбрано значение Не копировать.
  5. Различия в пространстве имен и именах классов будут создавать множество ошибок сборки на этом этапе. Например, если открыть созданные представления Visual Studio, вы увидите, что они имеют тип страницы, а не PhoneApplicationPage. В этом руководстве по переносу подробно рассматриваются различные темы, касающиеся разметки XAML и императивного кода. Но вы будете быстро выполнять следующие общие действия: измените "clr-namespace" на "using" в объявлениях префикса пространства имен в разметке XAML; используйте сопоставление пространства имен и классов раздела и команды Поиска и замены Visual Studio, чтобы внести массовые изменения в исходный код (например, замените "System.Windows" на "Windows.UI.Xaml"); и в редакторе императивного кода в Visual Studio используйте команды Разрешить и упорядочивать команды usings в контекстном меню для получения дополнительных целевых изменений.

Пакеты SDK расширения

Большинство API универсальной платформы Windows (UWP), которые будет использовать портированное приложение, реализованы в наборе API, известном как универсальное семейство устройств. Но некоторые из них реализованы в пакетах SDK для расширений, и Visual Studio распознает только API, реализованные семейством целевых устройств вашего приложения или любыми пакетами SDK для расширений, на которые вы ссылаетесь.

Если вы получаете ошибки компиляции о пространствах имен, типах или членах, которые не удалось найти, это, скорее всего, является причиной. Откройте тему API в справочной документации по API и перейдите в раздел "Требования", чтобы определить семейство устройств, для которых предназначена данная реализация. Если это не ваше семейство целевых устройств, то чтобы сделать API доступным для проекта, вам потребуется ссылка на пакет SDK расширений для этого семейства устройств.

Щелкните Project>Add Reference>Windows Universal>Extensions и выберите соответствующий пакет SDK расширений. Например, если API, которые вы хотите вызвать, доступны только в семействе мобильных устройств, и они были представлены в версии 10.0.x.y, выберите Дополнения Windows Mobile дляUWP.

Это добавит следующую ссылку на файл проекта:

<ItemGroup>
    <SDKReference Include="WindowsMobile, Version=10.0.x.y">
        <Name>Windows Mobile Extensions for the UWP</Name>
    </SDKReference>
</ItemGroup>

Имя и номер версии соответствуют папкам в установленном расположении пакета SDK. Например, приведенные выше сведения соответствуют этому имени папки:

\Program Files (x86)\Windows Kits\10\Extension SDKs\WindowsMobile\10.0.x.y

Если приложение не предназначено для семейства устройств, реализующих API, необходимо использовать класс ApiInformation для проверки наличия API перед его вызовом (это называется адаптивным кодом). Это условие будет оцениваться везде, где выполняется ваше приложение, но будет истинным только на тех устройствах, где API присутствует и доступен для вызова. Используйте только пакеты SDK расширения и адаптивный код после первой проверки наличия универсального API. Ниже приведены некоторые примеры.

Кроме того, см. манифест пакета приложения.

Максимизация разметки и повторного использования кода

Вы обнаружите, что небольшой рефакторинг и (или) добавление адаптивного кода (как описано ниже) позволит вам оптимально использовать разметку и код, который работает во всех семействах устройств. Ниже приведены дополнительные сведения.

  • Файлы, которые являются общими для всех семейств устройств, не требуют особого внимания. Эти файлы будут использоваться приложением во всех семействах устройств, на которых он работает. К ним относятся файлы разметки XAML, императивные файлы исходного кода и файлы ресурсов.
  • Приложение может обнаружить семейство устройств, на котором оно работает, и перейти к представлению, разработанному специально для этого семейства устройств. Дополнительные сведения см. в статье Обнаружение платформы, на которой работает ваше приложение.
  • Аналогичный прием, который может быть полезен при отсутствии альтернативы, — это дать файлу разметки или файлу ResourceDictionary (или папке, содержащей этот файл) специальное имя, благодаря чему он будет загружаться автоматически во время выполнения только в том случае, если приложение работает на определенном семействе устройств. Этот метод иллюстрируется в Bookstore1 пример.
  • Чтобы использовать функции, которые недоступны во всех семействах устройств (например, принтеры, сканеры или кнопка камеры), можно написать адаптивный код. См. третий пример в условной компиляции и адаптивного кода в этом разделе.
  • Если вы хотите поддерживать Windows Phone Silverlight и Windows 10, вы можете предоставить общий доступ к файлам исходного кода между проектами. Вот как это сделать: в Visual Studio щелкните правой кнопкой мыши на проект в обозревателе решений, выберите Добавить существующий элемент, выберите файлы для общего доступа, а затем щелкните Добавить как ссылку. Сохраните файлы исходного кода в общей папке в файловой системе, где проекты, которые ссылаются на них, могут их видеть, и не забудьте добавить их в систему управления версиями. Если вы можете организовать императивный исходный код так, чтобы большая часть, если не весь файл, была работоспособной на обеих платформах, то вам не нужно иметь две копии одного и того же файла. Вы можете упаковать любую логику для конкретной платформы в файл в директивы условной компиляции, где это возможно, или условия времени выполнения при необходимости. См. следующий раздел ниже и директивы препроцессора C# .
  • Для повторного использования на двоичном уровне, а не на уровне исходного кода, существуют переносимые библиотеки классов, поддерживающие подмножество API .NET, доступные в Windows Phone Silverlight, а также подмножество для приложений Windows 10 (.NET Core). Переносимые сборки библиотек классов бинарно совместимы с этими платформами .NET и другими. Используйте Visual Studio для создания проекта, предназначенного для переносимой библиотеки классов. См. Разработка кроссплатформенных приложений с помощью портативной библиотеки классов.

Условная компиляция и адаптивный код

Если вы хотите поддерживать Windows Phone Silverlight и Windows 10 в одном файле кода, это можно сделать. При просмотре проекта Windows 10 на страницах свойств проекта вы увидите, что проект определяет WINDOWS_UAP как символ условной компиляции. Как правило, для выполнения условной компиляции можно использовать следующую логику.

#if WINDOWS_UAP
    // Code that you want to compile into the Windows 10/11 app.
#else
    // Code that you want to compile into the Windows Phone Silverlight app.
#endif // WINDOWS_UAP

Если у вас есть код, который вы поделились между приложением Windows Phone Silverlight и приложением среды выполнения Windows 8.x, возможно, у вас уже есть исходный код с логикой, как показано ниже:

#if NETFX_CORE
    // Code that you want to compile into the Windows Runtime 8.x app.
#else
    // Code that you want to compile into the Windows Phone Silverlight app.
#endif // NETFX_CORE

Если это так, и если теперь вы хотите поддерживать Windows 10, то это также можно сделать.

#if WINDOWS_UAP
    // Code that you want to compile into the Windows 10/11 app.
#else
#if NETFX_CORE
    // Code that you want to compile into the Windows Runtime 8.x app.
#else
    // Code that you want to compile into the Windows Phone Silverlight app.
#endif // NETFX_CORE
#endif // WINDOWS_UAP

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

       Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested +=
            this.ViewModelLocator_BackRequested;

...

    private void ViewModelLocator_BackRequested(object sender, Windows.UI.Core.BackRequestedEventArgs e)
    {
        // Handle the event.
    }

Возможно, вы использовали условную компиляцию, чтобы ограничить обработку кнопки аппаратной камеры на Windows Phone. В Windows 10 кнопка аппаратной камеры — это концепция, определенная для семейства мобильных устройств. Так как один пакет приложения будет работать на всех устройствах, мы изменим условие времени компиляции на условие времени выполнения с помощью адаптивного кода. Для этого мы используем класс ApiInformation , чтобы во время выполнения проверять наличие класса HardwareButtons. HardwareButtons определен в пакете SDK для мобильных расширений, поэтому нам потребуется добавить ссылку на этот пакет SDK в наш проект для компиляции этого кода. Обратите внимание, что обработчик будет выполняться только на устройствах, поддерживающих типы, определенные в SDK для мобильных расширений, и это относится к семейству мобильных устройств. Таким образом, приведенный ниже код тщательно использует только доступные функции, хотя это делает иначе, чем условная компиляция.

       // Note: Cache the value instead of querying it more than once.
        bool isHardwareButtonsAPIPresent = Windows.Foundation.Metadata.ApiInformation.IsTypePresent
            ("Windows.Phone.UI.Input.HardwareButtons");

        if (isHardwareButtonsAPIPresent)
        {
            Windows.Phone.UI.Input.HardwareButtons.CameraPressed +=
                this.HardwareButtons_CameraPressed;
        }

    ...

    private void HardwareButtons_CameraPressed(object sender, Windows.Phone.UI.Input.CameraEventArgs e)
    {
        // Handle the event.
    }

Кроме того, см. Определение платформы, на которой запущено ваше приложение.

Манифест пакета приложения

Параметры проекта (включая ссылки на пакеты SDK расширений) определяют область поверхности API, которую может вызвать ваше приложение. Но манифест пакета приложения — это то, что определяет фактический набор устройств, на которые клиенты могут установить приложение из Магазина. Дополнительные сведения см. в примерах TargetDeviceFamily.

Стоит знать, как редактировать манифест пакета приложения, поскольку в последующих разделах обсуждается его использование для различных объявлений, возможностей и других параметров, необходимых некоторым функциям. Для его редактирования можно использовать редактор манифеста пакета приложения Visual Studio. Если обозреватель решений не отображается, выберите его из меню Вид. Дважды щелкните Package.appxmanifest. Откроется окно редактора манифеста. Выберите соответствующую вкладку, чтобы внести изменения, а затем сохранить изменения. Вы можете убедиться, что элемент pm:PhoneIdentity в манифесте перенесенного приложения соответствует тому, что находится в манифесте приложения, которое вы переносите (полные сведения см. в разделе pm:PhoneIdentity).

См. справочник по схеме манифеста пакета для Windows 10.

Следующая тема — устранение неполадок.