آموزش resource dictionaries در زامارین فرم

آموزش resource dictionaries در زامارین فرم

آموزش resource dictionaries در زامارین فرم

ResourceDictionary یک مخزن برای منابعی است که به وسیله برنامه های Xamarin.Form مورد استفاده قرار می‌گیرند. معمولا منابع در یک ResourceDictionary ذخیره می‌شوند که شامل styles، control templates ، data templates ، رنگ‌ها و converters می‌باشند.

در XAML، منابعی که در یک ResourceDictionary ذخیره می‌شوند را می‌توان با استفاده از StaticResource و DynamicResource  برای عناصر به کار برد. در C#، منابع را می‌توان در یک ResourceDictionary تعریف کرد و سپس با استفاده از یک indexer مبتنی بر string به عناصر ارجاع داده شود .

ایجاد یک resources در XAML

هر شی که از VisualElement مشتق ‌شده دارای یک Resources property است که می‌تواند حاوی ResourceDictionary باشد. به عنوان مثال Aplication  دارای ویژگی ResourceDictionary است که منابعی از جمله استایل ها و رنگ و غیره در ان تعریف می شود . به طور کلی به 4 روش می توان  ResourceDictionary را تعریف کرد .

تعریف در سطح view

تعریف ResourceDictionary در view برای عناصر صفحه به عنوان مثال  label , buttom و …. در این روش منابع فقط روی عنصر خاص اعمال می شود .

تعریف در سطح layout 

تعریف ResourceDictionary در layout  برای عناصر صفحه به عنوان مثال  Grid , StackLayout و …. در این روش منابع فقط  layout و فرزندان انها اعمال می شود .

تعریف در سطح Page

تعریف ResourceDictionary در Page در این روش منابع page و فرزندان انها اعمال می شود .

تعریف در سطح Aplication

تعریف ResourceDictionary در Aplication در این روش منابع روی کل برنامه اعمال می شود .

به استثنای implicit styles ها ، هر ResourceDictionary که تعریف می شود باید نامی منحصر به فرد x:Key  داشته باشد تا بتوان ان را فراخوانی کرد 

در فایل App.xaml زیر منابعی که در سطح Aplication  تعریف شده است را نشان می دهد

<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ResourceDictionaryDemo.App">
    <Application.Resources>

        <Thickness x:Key="PageMargin">20</Thickness>

        <!-- Colors -->
        <Color x:Key="AppBackgroundColor">AliceBlue</Color>
        <Color x:Key="NavigationBarColor">#1976D2</Color>
        <Color x:Key="NavigationBarTextColor">White</Color>
        <Color x:Key="NormalTextColor">Black</Color>

        <!-- Implicit styles -->
        <Style TargetType="{x:Type NavigationPage}">
            <Setter Property="BarBackgroundColor"
                    Value="{StaticResource NavigationBarColor}" />
            <Setter Property="BarTextColor"
                    Value="{StaticResource NavigationBarTextColor}" />
        </Style>

        <Style TargetType="{x:Type ContentPage}"
               ApplyToDerivedTypes="True">
            <Setter Property="BackgroundColor"
                    Value="{StaticResource AppBackgroundColor}" />
        </Style>

    </Application.Resources>
</Application>

در کد بالا یک سبک Thickness (ضخامت ) و 4 نوع رنگ با نام های منحصر به فرد و 2 استایل تعریف شده است

استفاده از resources در XAML

هر resources یک کلید دارد که با استفاده از :X  مشخص می‌شود ، که تبدیل به کلید ResourceDictionary می‌شود. این کلید با استفاده از StaticResource و DynamicResource قابل استفاده است .

StaticResource شبیه DynamicResource  است وهر دو با استفاده از کلید X:Key به مقدار مشخص شده دسترسی دارند با این تفاوت که StaticResource برای ResourceDictionary های تک مقداری  است ولی DynamicResource برای دسترسی به ResourceDictionary های چند مقداری به کار می رود .

در مثال زیر نحوه استفاده نشان داده شده است 

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ResourceDictionaryDemo.HomePage"
             Title="Home Page">
    <StackLayout Margin="{StaticResource PageMargin}">
        <StackLayout.Resources>
            <!-- Implicit style -->
            <Style TargetType="Button">
                <Setter Property="FontSize" Value="Medium" />
                <Setter Property="BackgroundColor" Value="#1976D2" />
                <Setter Property="TextColor" Value="White" />
                <Setter Property="CornerRadius" Value="5" />
            </Style>
        </StackLayout.Resources>

        <Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries." />
        <Button Text="Navigate"
                Clicked="OnNavigateButtonClicked" />
    </StackLayout>
</ContentPage>

در مثال بالا استایل هایی که بطور ضمنی در سطح Application  تعریف شده است به contentPage  اعمال می شود . به StackLayout ویژگی Thickness که از نوع StaticResource و تک مقداری است و در سطح Application  تعریف شده است ، اعمال می شود . به Button استایل های ضمنی که در StackLayout.Resources تعریف شده است ، اعمال می شود .

 

Resources هایی که برای یک صفحه خاص تعریف می شوند نباید در سطح Application  تعریف شوند چون باعث کاهش performance برنامه می شود

رفتار جستجوی منابع (Resource lookup behavior)

فرایند جستجو کلید در منابع (resource dictionary) با StaticResource or DynamicResource به شرح زیر است

  1. کلید درخواستی در صورت وجود در resource dictionary برای عنصری که ویژگی را تنظیم می کند بررسی می شود. اگر کلید درخواستی پیدا شود ، مقدار آن بازگردانده می شود و روند جستجو خاتمه می یابد.
  2. اگر کلید پیدا نشد ، روند جستجو  سمت بالا  و والد خود ، ادامه پیدا می کند ، اگر کلید درخواستی پیدا شود ، مقدار آن بازگردانده می شود و روند جستجو خاتمه می یابد. در غیر این صورت روند به سمت بالا ادامه می یابد تا رسیدن به عنصر ریشه.
  3. اگر مطابقت در عنصر ریشه یافت نشد ، resource dictionary سطح Application را بررسی می شود.
  4. اگر باز هم کلید پیدا نشد برنامه خطای XamlParseException را پرتاب می کند.

لغو منابع ( Override resources )

هنگامی که resource dictionary تعریف می شود ، منابعی که در پایین‌ترین نمودار درختی در نظر گرفته می‌شوند، نسبت به آن‌هایی که بالاتر هستند اولویت دارند. به عنوان مثال، اگر یک کلید در سطح Application و سطح page  تعریف شود کلید سطح Application  نادیده گرفته خواهد شد. همین روند هر چه به سطح های پایین تر حرکت کنیم صادق است .

resource dictionaries مستقل 

  1. resource dictionaries ها را می توانیم در یک فایل جداگانه ذخیره کنیم و در برنامه هر جا نیاز بود استفاده کرد .
  2. برای ایجاد چنین فایلی ابتدا یک پرونده جدید از نوع ContentPage  یا ContentView در پروژه ایجاد می کنیم . سپس فایل کد Code-behind ان را حذف می کنیم (نیازی به کد سی شارپ نیست )
  3. نام دلخواهی برای ان انتخاب می کنیم
  4. خصوصین x:Class  را از تگ روت صفحه حذف می کنیم

مثال XAML زیر یک ResourceDictionary با نام MyResourceDictionary.xaml را نشان می دهد

<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <DataTemplate x:Key="PersonDataTemplate">
        <ViewCell>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0.5*" />
                    <ColumnDefinition Width="0.2*" />
                    <ColumnDefinition Width="0.3*" />
                </Grid.ColumnDefinitions>
                <Label Text="{Binding Name}"
                       TextColor="{StaticResource NormalTextColor}"
                       FontAttributes="Bold" />
                <Label Grid.Column="1"
                       Text="{Binding Age}"
                       TextColor="{StaticResource NormalTextColor}" />
                <Label Grid.Column="2"
                       Text="{Binding Location}"
                       TextColor="{StaticResource NormalTextColor}"
                       HorizontalTextAlignment="End" />
            </Grid>
        </ViewCell>
    </DataTemplate>
</ResourceDictionary>

در مثال بالا ، ResourceDictionary شامل یک Resource است که از نوع DataTemplate است. MyResourceDictionary.xaml را می توان با ادغام آن در resource dictionary منابع دیگر استفاده کرد.

ادغام resource dictionaries های محلی

با ایجاد یک شی از  ResourceDictionary که ویژگی Source روی نام فایل XAML با منابع تنظیم شده است ، می توان یک فایل محلی ResourceDictionary را در ResourceDictionary دیگری ادغام کرد

<ContentPage ...>
    <ContentPage.Resources>
        <!-- Add more resources here -->
        <ResourceDictionary Source="MyResourceDictionary.xaml" />
        <!-- Add more resources here -->
    </ContentPage.Resources>
    ...
</ContentPage>

این نحو کلاس MyResourceDictionary را نمونه سازی نمی کند. درعوض ، این پرونده XAML را ارجاع می دهد. به همین دلیل ، هنگام تنظیم ویژگی Source ، یک فایل پشت کد مورد نیاز نیست و ویژگی x: Class را می توان از برچسب ریشه فایل MyResourceDictionary.xaml حذف کرد.

ویژگی Source فقط از XAML قابل تنظیم است.

ادغام resource dictionaries ها با اسمبلی های دیگر

resource dictionaries را از منابه مختلف می توان ادغام کرد توجه داشته باشید که resource dictionaries که قراره ادغام بشه باید دارای صفت x:Class  باشد 

در مثال زیر دو  resource dictionaries به page  اضافه شده است

<ContentPage ...
             xmlns:local="clr-namespace:ResourceDictionaryDemo"
             xmlns:theme="clr-namespace:MyThemes;assembly=MyThemes">
    <ContentPage.Resources>
        <ResourceDictionary>
            <!-- Add more resources here -->
            <ResourceDictionary.MergedDictionaries>
                <!-- Add more resource dictionaries here -->
                <local:MyResourceDictionary />
                <theme:LightTheme />
                <!-- Add more resource dictionaries here -->
            </ResourceDictionary.MergedDictionaries>
            <!-- Add more resources here -->
        </ResourceDictionary>
    </ContentPage.Resources>
    ...
</ContentPage>

شما فقط می توانید یک تگ ResourceDictionary.MergedDictionaries تعریف کنید ولی به هر تعداد می توانید ResourceDictionary به صفحه پیوست کنید

زمانی که منابع ResourceDictionary با هم ادغام می شه زامارین یک کلید اشتراکی منحصر به فرد برای انها تولید می کند و به ترتیب الویت زیر انها فراخوانی می شوند

  1. ResourceDictionary محلی
  2. منابعی که داخل MergedDictionaries تعریف شده است

برای کارایی و بهبود performance لازم است منابعی که مورد نیاز نیست در ResourceDictionary تعریف نشود

دانلود مثال و نمونه کد

افزودن نظر جدید

در صورتی که وارد نشده باشید نظر شما بعد از تایید ادمین منتشر خواهد شد

نظرات بدون نمایش ایمیل و شماره تماس منتشر خواهد شد

وارد کردن فیلد های ستاره دار ( * ) الزامی است

 
 
 
 
 

 

0 نظر ثبت شده است