UWP (Universal Windows Platform) का परिचय — शीघ्र आरंभ

1. Xaml

1.1. XAML परिचय

  • XAML अवलोकन
  • मुख्य रूप से दृश्य UI तत्वों को बनाने के लिए उपयोग किया जाता है।
  • Xaml का बुनियादी वाक्यविन्यास XML पर आधारित है।
  • एक namespace का उपनाम घोषित करें:
xmlns:controls="using:Common.Controls"
  • namespace में घोषित कक्षा (class) का उपयोग करें:
<controls:MyControl />
  • पुनः उपयोग योग्य संसाधन (Resource),

    x:Key

<Style x:Key="TextBlock_Style" />
  • नियंत्रण तत्व का नाम (Name),

x:Name

Xaml:

<MyControl x:Name="myControl" />

C#:

private MyControl myControl;
  • स्थानीयकरण

    x:Uid

<TextBlock x:Uid="sampleText" />

1.2. सबसे बुनियादी नियंत्रण (Control) – TextBlock, Button

<Page x:Class="MyPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <TextBlock Text="UWP Introduction" />
        <Button Content="UWP Introduction" Click="Button_Click" />
    </StackPanel>
</Page>

2. MVVM

MVVM विस्तृत परिचय

View <=> ViewModel <=> Model

  • View में यथासंभव केवल UI प्रदर्शन की सामग्री होनी चाहिए, अधिकांश View Xaml भाषा का उपयोग करके पूरा किया जाता है;
  • ViewModel में यथासंभव व्यावसायिक प्रसंस्करण तर्क नहीं होना चाहिए, बल्कि Model के फ़ंक्शन को कॉल करके कार्यों को पूरा किया जाता है;
  • Model में यथासंभव सभी व्यावसायिक डेटा और तर्क होने चाहिए, और यह View और ViewModel पर यथासंभव निर्भर नहीं होना चाहिए;

3. ViewModel और Model के बीच इंटरैक्शन

3.1. ViewModel द्वारा Model के डेटा को नियंत्रित करना

ViewModel:

public class ViewModel
{
    private Model model;
    private ChangeA()
    {
        this.model.A = "A";
    }
}

Model:

public class Model
{
    public string A { get; set; }
    public string B { get; set; }
}

3.2. Model द्वारा ViewModel को सूचित करना – event

ViewModel:

public class ViewModel
{
private Model model;
    private ChangeA()
    {
        r.BEventArgs += this.Handler;
    }
    private void Handler(object sender, EventArgs e)
    {
        AnyActions();
    }
}

Model:

public delegate void BChangedHandler(object sender, EventArgs e);

public class Model
{
    public string A { get; set; }
    private string _B;
    public string B
    {
        get { return this._B; }
        set
        {
            this._B = value;
            if (BEventArgs != null)
            {
                BEventArgs(this, new EventArgs());
            }
        }
    }
    public event BChangedHandler BEventArgs;
}

4. View और ViewModel के बीच इंटरैक्शन

4.1. डेटा बाइंडिंग

4.1.1. ViewModel में बाइंडिंग

View:

<TextBlock Text={Binding SampleText} />

ViewModel:

public string SampleText { get; set; }

4.1.2. अन्य Control में बाइंडिंग

View:

<TextBlock x:Name="TextBlock1" Text="SampleText" />
<Button Content="{Binding ElementName=TextBlock1, Path= Text}" />

4.1.3. DataContext निर्दिष्ट करें

public ViewModelClass ViewModel { get; set; }

...
SpecifiedControl.DataContext = ViewModel;
...

5. (View और ViewModel) संदेश सूचना कार्यान्वयन – INotifyPropertyChanged

जब SampleText में परिवर्तन होता है, तो इस property से बाउंड DependencyProperty को सूचित किया जाता है

public class MyControlViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void Notify(string propName)
        {
            if (this.PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }

        private string _sampleText;
        public string SampleText
        {
            get
            {
                return _sampleText;
            }
            set
            {
                _sampleText = value;
                Notify(nameof(SampleText));
            }
        }
    }

या ViewModelBase को इनहेरिट करें

public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void Notify(string propName)
        {
            if (this.PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }
    }

6. (View और ViewModel) ListView को संदेश सूचना लागू करने वाले स्रोत से बाइंड करें – ObservableCollection

ListView

ListView में संदेश सूचना वाले ItemSource के साथ बाइंडिंग लागू करें

View:

<ListView ItemsSource="{Binding Items}">

ViewModel:

public ObservableCollection<Recording> Items { get; set; }
  • ObservableCollection केवल आइटम जोड़ने/हटाने या पूरी सूची को रिफ्रेश करते समय ही संदेश सूचना उत्पन्न करती है;
  • यदि आइटम Recording की सामग्री बदलने पर इंटरफ़ेस को सूचित करने की आवश्यकता है, तो Recording को INotifyPropertyChanged लागू करना होगा।

7. (View) ListView की Item टेम्पलेट (DataTemplate | UserControl)

7.1. DataTemplate

View:

<ListView ItemsSource="{Binding Items}">
    <ListView.ItemTemplate>
        <DataTemplate DataType="local:Recording">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding A}" />
                <TextBlock Text="{Binding B}" />
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

ViewModel:

public ObservableCollection<RecordingViewModel> Items { get; set; }

public class RecordingViewModel : INotifyPropertyChanged
{
    ...
    INotifyPropertyChanged लागू करें
    ...

    private Recording _recording;

    public string A
    {
        get
        {
            return this._recording.A;
        }
        set
        {
            this._recording.A = value;
            Notify(nameof(A));
        }
    }

    public string B { get; set; } = this._recording.B;

    public RecordingViewModel (Recording recording)
    {
        this._recording = recording;
    }
}

Model:

public class Recording
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
    ... ...
}

तुलना:

ViewModel/Model अलगाव

7.2. UserControl

7.2.1. DependencyProperty

  • Dependency Properties Overview
  • केवल DependencyProperty अन्य property से बाइंड हो सकती है, और केवल बाइंडिंग View में संदेश सूचना लागू कर सकती है
  • इसमें प्राथमिकता होती है

View:

<control:MyControl Text="App is on searching" IsSearching="{Binding ViewModel.IsSearching}" />

ViewModel:

public class MyControl
{
...
public static readonly DependencyProperty IsSearchingProperty =
    DependencyProperty.Register
    (
        "IsSearching", typeof(Boolean),
        typeof(MyControl), null
    );

public bool IsSearching
{
    get { return (bool)GetValue(IsSearchingProperty); }
    set { SetValue(IsSearchingProperty, value); }
}
...
}

8. (ViewModel और Model) डेटा रूपांतरण – IValueConverter

ViewModel और Model के बीच डेटा रूपांतरण के लिए IValueConverter का उपयोग किया जा सकता है।

public class ShowAllButtonVisibilityConverter:IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            if (value is IList)
            {
                int count = (value as IList).Count;
                if (count > 3)
                {
                    return Windows.UI.Xaml.Visibility.Visible;
                }
            }
            return Windows.UI.Xaml.Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            if (value is IList)
            {
                int count = (value as IList).Count;
                if (count > 3)
                {
                    return Windows.UI.Xaml.Visibility.Visible;
                }
            }
            return Windows.UI.Xaml.Visibility.Collapsed;
        }

9. (View) Control की Style संशोधित करें

9.1. Control के अंदर Style को कस्टमाइज़ करें

View:

<TextBlock Foreground="Red" Text="SampleText" />

9.2. एकसमान Style का उपयोग करें – ResourceDictionary

View:

<Window.Resources>
    <ResourceDictionary>
        <Style TargetType="TextBlock" x:Key="ImportantText">
            <Setter Property="Foreground" Value="Red" />
        </Style>
    </ResourceDictionary>
</Window.Resources>
...
<TextBlock Text="SampleText" Style={StaticResource ImportantText} />

9.3. ThemeResource का उपयोग करें

View:

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.ThemeDictionaries>
            <ResourceDictionary x:Key="Light">
                <Style TargetType="TextBlock" x:Key="ImportantText">
                    <Setter Property="Foreground" Value="Red" />
                </Style>
            </ResourceDictionary>

            <ResourceDictionary x:Key="Dark">
                <Style TargetType="TextBlock" x:Key="ImportantText">
                    <Setter Property="Foreground" Value="Yellow" />
                </Style>
            </ResourceDictionary>

            <ResourceDictionary x:Key="HighContrast">
                <Style TargetType="TextBlock" x:Key="ImportantText">
                    <Setter Property="Foreground" Value="Black" />
                </Style>
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>
    </ResourceDictionary>
</Window.Resources>
...
<TextBlock Text="SampleText" Style={ThemeResource ImportantText} />

10. Panel का उपयोग करें

10.1. Grid

विशेषताएं:

  • डिफ़ॉल्ट Height/Width मूल तत्व के बराबर होता है;

सुझाव:

  • Grid में चाइल्ड तत्वों के लेआउट आकार को परिभाषित करें;
  • अनुपात में प्रदर्शित करें;

10.2. StackPanel

विशेषताएं:

  • यह मूल तत्व की सीमा से परे जा सकता है;
  • Height या Width पैनल के अंदर के तत्वों के साथ बदलता है;

सुझाव:

  • Padding और अनुपात का लचीले ढंग से उपयोग करें;
  • Control के बाहर जाने से रोकने के लिए, मूल तत्व में StackPanel के Width या Height को एक मान दें;

11. (View) अनुकूली UI (Adaptive UI)

  • VisualStateManager.VisualStateGroup का उपयोग करें
<VisualStateGroup>
    <VisualState x:Name="WideLayout">
        <VisualState.StateTriggers>
            <AdaptiveTrigger x:Name="WideLayoutTrigger" MinWindowWidth="1280" />
        </VisualState.StateTriggers>
        <VisualState.Setters>
            <Setter Target="SystemUpdateSideGrid.Width" Value="800" />
            <Setter Target="SystemUpdateSideGrid.Grid.Row" Value="0" />
        </VisualState.Setters>
    </VisualState>

    <VisualState x:Name="MidLayout">
        <VisualState.StateTriggers>
            <AdaptiveTrigger x:Name="MidLayoutTrigger" MinWindowWidth="700" />
        </VisualState.StateTriggers>
        <VisualState.Setters>
            <Setter Target="SystemUpdateSideGrid.Width" Value="400" />
            <Setter Target="SystemUpdateSideGrid.Grid.Row" Value="1" />
        </VisualState.Setters>
    </VisualState>
    ...
</VisualStateGroup>

12. लेआउट सिद्धांत

  • तत्वों के आयामों को स्पष्ट रूप से निर्धारित न करें;
  • तत्वों की स्थिति निर्दिष्ट करने के लिए स्क्रीन निर्देशांक का उपयोग न करें;
  • कंटेनर के भीतर चाइल्ड तत्व उपलब्ध स्थान साझा करते हैं;
  • नेस्टेड लेआउट कंटेनर;

13. स्थानीयकरण (Localization)

  • x:Uid का उपयोग करें, तत्व का अद्वितीय पहचानकर्ता
    <TextBlock x:Uid="S_TextBlock1" />
  • Resources File का उपयोग करें
    <data name="S_TextBlock1.Text" xml:space="preserve">
        <value>Sample text</value>
    </data>

14. नामकरण सम्मेलन

बड़ा उट केस (big camel-case): firstName

छोटा उट केस (little camel-case): FirstName

  • Class: बड़ा उट केस
  • Property: बड़ा उट केस
  • Field: छोटा उट केस (little camel-case) जिसमें प्रिफिक्स “_” हो
  • Xaml में Control: छोटा उट केस

15. ध्यान दें

  • ViewModel में Property का नाम बदलते समय सावधान रहें, क्योंकि Xaml में Binding का नाम रिफैक्टरिंग (Refactoring) के साथ नहीं बदलता है;