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

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

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

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

  1. Запустите Microsoft Visual Studio 2015 и создайте новый проект "Пустое приложение (Windows Universal)". Дополнительные сведения см. в статье Начало работы с приложением среда выполнения Windows 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. Дважды убедитесь, что Действие при сборке ваших визуальных активов установлено на Содержимое и Копировать в выходной каталог установлено на Не копировать.
  5. Различия в пространстве имен и именах классов создает множество ошибок построения на этом этапе. Например, если вы открыли представления, созданные в Visual Studio, вы увидите, что они относятся к типу Page, а не PhoneApplicationPage. Также существует множество различий в разметке XAML и императивном коде, которые подробно рассматриваются в следующих разделах этого руководства по переносу. Но вы быстро продвинетесь вперед просто выполняя следующие общие шаги: в разметке XAML измените clr-namespace на using в объявлениях префиксов пространства имен; используйте раздел Сопоставление пространств имен и классов и команду Visual Studio Поиск и замена для внесения массовых изменений в исходный код (например, замените System.Windows на Windows.UI.Xaml); в редакторе императивного кода в Visual Studio используйте команды Разрешить и Упорядочение Using в контекстном меню для выполнения более адресных изменений.

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

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

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

Щелкните ProjectAdd ReferenceWindows UniversalExtensions (Добавить >эталонные>универсальные> расширения Windows) и выберите соответствующий пакет SDK расширения. Например, если нужные API-интерфейсы доступны только для семейства мобильных устройств и они появились в версии 10.0.x.y, выберите Windows Mobile Extensions для 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. Если Solution Explorer (Обозреватель решений) не отображается, выберите его в меню View (Вид). Дважды щелкните Package.appxmanifest. Откроется окно редактора манифестов. Выберите соответствующую вкладку, чтобы внести изменения, а затем сохраните эти изменения. Возможно, вы хотите убедиться, что элемент pm:PhoneIdentity в переносимом манифесте приложения соответствует манифесту приложения, которое вы переносите (подробнее см. в разделе pm:PhoneIdentity).

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

Следующий раздел называется Устранение неполадок.