مشخصات مقاله
پشتیبانی از برنامه های WinRT
کلیه حقوق مادی و معنوی این مقاله متعلق به آموزشگاه تحلیل داده می باشد و هر گونه استفاده غیر قانونی از آن پیگرد قانونی دارد.
پشتیبانی از برنامه های WinRT
در این مرحله یاد خواهید گرفت چطور می توانیم قابلیت پشتیبانی از WinRT را به برنامه اضافه کنیم. یعنی بتوانید یک برنامه Universal بسازید که از Xamarin Forms for Windows (Preview) استفاده کند.
همانطور که در تصاویر زیر مشاهده میکنید یک پروژه جدید براساس قالب Universal App ایجاد میکنیم.
نتیجه عبارت است از:
حالا مرجع ENEI.SessionsApp را به پروژه WinRT اضافه می کنیم. مانند تصاویر زیر:
در برنامه Windows Phone 8.1 (WinRT) با خطایی مانند تصویر زیر مواجه خواهید شد:
این خطا یعنی اینکه ENEI.SessionsApp یک Portable Class Library یا به اختصار PCL است که بوسیله Windows Phone 8.1 (WinRT) پشتیبانی نمی شود. به این ترتیب باید برای پشتیبانی، خصوصیات پروژه PCL را مطابق شکل زیر تنظیم کنیم:
پس از آن مراجع لازم به هر پروژه اضافه خواهد شد:
قبل از شروع کد نویسی، لازم است بسته Xamarin Forms Windows (Preview) NuGet Package را نصب کنید:
در حالت کلی، نباید تغییرات زیادی در برنامه های WinRT ایجاد کنیم. قبل از هر چیز باید تنظیمات لازم را در Xamarin Forms ایجاد کنید. با استفاده از متد OnLaunched در کلاس App.xaml.cs تغییراتی مانند کد زیر ایجاد میکنیم:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
#if DEBUG
if (System.Diagnostics.Debugger.IsAttached)
{
this.DebugSettings.EnableFrameRateCounter = true;
}
#endif
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
// TODO: change this value to a cache size that is appropriate for your application
rootFrame.CacheSize = 1;
global: Xamarin.Forms.Forms.Init(e);
}
}
در سایر پلتفرم ها نیز، متد Init، Xamarin Form ها را initialize می کند و باید LaunchActivatedEventArgs ارسال شود.
علاوه بر این باید یکسری تغییرات در سازنده MainPage در تمام برنامه های WinRT ایجاد کنیم:
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
LoadApplication(new ENEI.SessionsApp.App());
}
و نوع صفحه نیز به شکل زیر تغییر کند:
در Windows Phone 8.1 (WinRT)
<forms:WindowsPage
x:Class="ENEI.SessionsApp.WinRT.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:forms="using:Xamarin.Forms.Platform.WinRT"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Foreground="Black"
Background="White">
در Windows 8.1 Store App (WinRT)
<forms:WindowsPage
x:Class="ENEI.SessionsApp.WinRT.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:forms="using:Xamarin.Forms.Platform.WinRT"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Foreground="Black"
Background="White">
حالا باید از ابتدا رنگ پس زمینه NavigationPage را به سفید تغییر دهید.
MainPage = new NavigationPage(new SessionsView())
{
BarBackgroundColor = Color.White,
BarTextColor = Color.Black,
BackgroundColor = Color.White,
};
حالا Header را درست می بینیم. اما تصاویر منو نمایش داده نشده اند. چون هر تصویر به شکل زیر تعریف شده است:
<Image Grid.Column="7">
<Image.WidthRequest>
<OnPlatform Android="30" WinPhone="48" iOS="30" x:TypeArguments="x:Double" />
Image.WidthRequest>
<Image.HeightRequest>
<OnPlatform Android="30" WinPhone="48" iOS="30" x:TypeArguments="x:Double" />
Image.HeightRequest>
<Image.Source>
<OnPlatform x:TypeArguments="ImageSource">
<OnPlatform.iOS>
<FileImageSource File="ic_action_list.png" />
OnPlatform.iOS>
<OnPlatform.Android>
<FileImageSource File="ic_action_list.png" />
OnPlatform.Android>
<OnPlatform.WinPhone>
<FileImageSource File="Images/ic_action_list.png" />
OnPlatform.WinPhone>
OnPlatform>
Image.Source>
<Image.GestureRecognizers>
<TapGestureRecognizer x:Name="DetailsGesture" CommandParameter="{Binding}" Tapped="DetailsGesture_OnTapped" />
Image.GestureRecognizers>
Image>
در اینجا برای دریافت تصویر و تنظیم طول و عرض آن ها، از OnPlatform استفاده کرده ایم. البته استفاده از آن در نسخه پیش نمایش مجاز نیست. اما بعداً برای برنامه های Windows نیز مانند سایر پلتفرم ها کار میکند.
به این ترتیب برای حصول اطمینان از بارگذاری شدن تصویر و استفاده از Converters یک قطعه کد به شکل زیر می نویسیم:
<ContentPage.Resources>
<ResourceDictionary>
<converters:FavoriteImageConverter x:Key="FavoriteImageConverter" />
<converters:ImageSizeConverter x:Key="ImageSizeConverter"/>
<converters:ImageUrlConverter x:Key="ImageUrlConverter"/>
<converters:RowHeightConverter x:Key="RowHeightConverter"/>
ResourceDictionary>
ContentPage.Resources>
و:
<Image Grid.Column="7"Source="{Binding Converter={StaticResource ImageUrlConverter}, ConverterParameter=Details}" HeightRequest="{Binding Converter={StaticResource ImageSizeConverter}}" WidthRequest="{Binding Converter={StaticResource ImageSizeConverter}}">
<Image.GestureRecognizers>
<TapGestureRecognizer x:Name="DetailsGesture" CommandParameter="{Binding}"Tapped="DetailsGesture_OnTapped" />
Image.GestureRecognizers>
Image>
که در آن Converters به شکل زیر تعریف می شود:
در ImageSizeConverter برای تعیین طول و عرض تصویر :
public class ImageSizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null)
{
if (Device.OS == TargetPlatform.Android || Device.OS == TargetPlatform.Windows)
{
return 48;
}
if (Device.OS == TargetPlatform.iOS)
{
return 30;
}
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
در ImageUrlConverter برای تعیین مسیر تصاویر:
public class ImageUrlConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (parameter != null && !string.IsNullOrEmpty(parameter.ToString()))
{
var imageUrl = string.Empty;
switch (parameter.ToString())
{
case "Like":
imageUrl = Device.OS == TargetPlatform.WinPhone || Device.OS == TargetPlatform.Windows ?
"Images/ic_action_like.png" :
"ic_action_like.png";
break;
case "Share":
imageUrl = Device.OS == TargetPlatform.WinPhone || Device.OS == TargetPlatform.Windows ?
"Images/ic_action_share_2.png" :
"ic_action_share_2.png";
break;
case "Details":
imageUrl = Device.OS == TargetPlatform.WinPhone || Device.OS == TargetPlatform.Windows ?
"Images/ic_action_list.png" :
"ic_action_list.png";
break;
}
return ImageSource.FromFile(imageUrl);
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
در RowHeightConverter، سایز هر سطر از ListView به شکل زیر تعریف می شود:
public class RowHeightConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null)
{
if (Device.OS == TargetPlatform.Android || Device.OS == TargetPlatform.iOS)
{
return 150;
}
if (Device.OS == TargetPlatform.WinPhone)
{
return 180;
}
if (Device.OS == TargetPlatform.Windows)
{
return 200;
}
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
حالا اگر برنامه را اجرا کنید با چیزی مانند تصویر زیر مواجه خواهید شد: