نحوه استفاده از الگوی MVVM درWPF

سه شنبه 10 آذر 1394

در این مقاله یک مثال در WPF با استفاده از روش MVVM ایجاد خواهیم کرد. و روش استفاده از این الگو را به همراه این مثال توضیح خواهیم داد.

 نحوه استفاده از الگوی  MVVM  درWPF

در این مقاله یک مثال در WPF   با استفاده از روش  MVVM  ایجاد خواهیم کرد. و روش استفاده از این الگو را به همراه این مثال توضیح خواهیم داد.

می خواهیم مشخصات یا اطلاعاتی از کارمندان را بر اساس کد کارمندی آنها که توسط کاربر وارد می شود با استفاده از روش MVVM   نمایش دهیم .

یک پروژه جدید WPF  به همراه فایلهای زیر ایجاد میکنیم.

MainWindow.Xaml    .   (یک  View)

MainWindow.Xaml.Cs    .  ، در روش  MVVM  ، کدهای پشت صفحه (Codebehind) نقش بسیار کمی بازی میکند.

SearchEmpVM.CS    . (یک  View Model)

EmpCls.CS    . (یک  Model)

 

کلاس EmpCls.cs

این کلاس به صورت زیر پر می شود :

class EmpCls
    {
        private int _empNo;
        public int EmpNo
        {
            get
            {
                return _empNo;
            }
            set
            {
                _empNo = value;
            }
        }
        private string _name;
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        private string _designation;
        public string Designation
        {
            get
            {
                return _designation;
            }
            set
            {
                _designation = value;
            }
        }
        private string _department;
        public string Department
        {
            get
            {
                return _department;
            }
            set
            {
                _department = value;
            }
        }  
    }

و کدهای زیر در View یا MainWindow.Xaml قرار خواهند گرفت.

<Window x:Class="SampleWPFMVVM.MainWindow"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"     
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    
          mc:Ignorable="d"    
          xmlns:vm="clr-namespace:SampleWPFMVVM.ViewModel"    
      Title="مرجع تخصصی برنامه نویسان" Height="350" Width="333"    
        x:Name="Window">
    <Window.DataContext>
        <vm:SearchEmpVM />
    </Window.DataContext>
    <Grid FlowDirection="RightToLeft">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" ></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition  Height="auto" ></RowDefinition>
        </Grid.RowDefinitions>


        <StackPanel>
            <Grid Margin="0,51,0,-48" Grid.RowSpan="4">
                <Grid.RowDefinitions>
                    <RowDefinition Height="auto"></RowDefinition>
                    <RowDefinition Height="auto"></RowDefinition>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="auto"/>
                    <ColumnDefinition Width="auto"/>
                </Grid.ColumnDefinitions>
                <Label   Grid.Row="0" Grid.Column="0" Content=" کد کارمندی:"/>
                <TextBox x:Name="txtEmpId1"   Text="{Binding  ElementName=Window,Path=DataContext.EmpId,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="1" ></TextBox>
                <StackPanel DataContext="{Binding SearchCls}" Grid.Column="1" Grid.Row="1">
                    <GroupBox>
                        <GroupBox.HeaderTemplate>
                            <DataTemplate>
                                <Label    Content=" اطلاعات کارمندان"/>

                            </DataTemplate>
                        </GroupBox.HeaderTemplate>
                        <Grid >
                            <Grid.RowDefinitions>
                                <RowDefinition Height="26*"/>
                                <RowDefinition Height="26*"/>
                                <RowDefinition Height="26*"/>
                                <RowDefinition Height="26*"/>
                                <RowDefinition Height="26*"/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <Label   Grid.Row="0" Grid.Column="0" Content="نام:" Grid.ColumnSpan="3" />
                            <TextBox  Text="{Binding Name}" Grid.Row="0" Grid.Column="3" Width="174"/>
                            <Label   Grid.Row="1" Grid.Column="0" Content="نقش:" Grid.ColumnSpan="3"/>
                            <TextBox Text="{Binding Designation}" Grid.Row="1" Grid.Column="3" Width="174"/>

                            <Label   Grid.Row="2" Grid.Column="0" Content="بخش:" Grid.ColumnSpan="3" />
                            <TextBox  Text="{Binding Department}"  Grid.Row="2" Grid.Column="3" Width="174"/>

                        </Grid>



                    </GroupBox>
                </StackPanel>

            </Grid>

        </StackPanel>



    </Grid>


</Window>

 

نکاتی درباره کدهای بالا در زیر آمده است.

Xmlns:vm="clr-namesspace:SampleWPFMVVM.viewModel"   .1   -  این جمله فضای نام مورد نیاز  ViewModel ما  (SearchEmpVM.CS) را وارد میکند.

2.     خط های زیر، کلاس  ViewModel  را به عنوان DataContext به فرم اتصال می دهد.

<Window.DataContext>
        <vm:SearchEmpVM />
    </Window.DataContext>

3.    در کد زیر ویژگی  EmpId از کلاس  ViewModel  پر میشود.

<TextBox x:Name="txtEmpId1"   Text="{Binding  ElementName=Window,Path=DataContext.EmpId,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="1" ></TextBox>

4.    کد زیر ویژگی SearchCls را پر میکند. این خاصیت یک شیء از کارمندان مورد جستجو در کلاس  EmpClsرا نگهداری میکند.

<StackPanel DataContext="{Binding SearchCls}" Grid.Column="1" Grid.Row="1">

5.    کد زیر ویژگی  Name  را از کلاس SearchCls پر خواهد کرد. پس هرجا که مقداری به ویژگی Name  انتساب داده شد ، مقدار در textbox  نشان داده خواهد شد.

<TextBox  Text="{Binding Name}" Grid.Row="0" Grid.Column="3" Width="174"/>

 

ViewModel(SearchEmpVM.CS)

این قسمت شامل منطق کاری زیر می باشد:

class SearchEmpVM : INotifyPropertyChanged
    {
        List<EmpCls> EmpList = new List<EmpCls>();

        public SearchEmpVM()
        {
            // Add sample employee details into employee list    
            EmpList.Clear();
           
            EmpList.Add(new EmpCls { EmpNo = 1, Name = "سلطانیه", Department = "نرم افزار", Designation = "برنامه نویس" });
            EmpList.Add(new EmpCls { EmpNo = 2, Name = " علی تمیمی", Department = "IT", Designation = "TFS" });

            EmpList.Add(new EmpCls { EmpNo = 3, Name = "اسماعیلی", Department = "IT", Designation = "واحد تست" });
            EmpList.Add(new EmpCls { EmpNo = 4, Name = "تقیان", Department = "IT", Designation = "توسعه دهنده دیتابیس" });

        }


        #region properties

        private EmpCls _searchcls = new EmpCls();
        public EmpCls SearchCls
        {
            get { return _searchcls; }

            set
            {
                _searchcls = value;

                RaisePropertyChanged("SearchCls");

            }
        }

        private int _empid;
        public int EmpId
        {
            get
            {
                return _empid;

            }

            set
            {
                _empid = value;

                RaisePropertyChanged("EmpId");
                PopulteEmpDetails(_empid);
            }


        }


        #endregion

        private void PopulteEmpDetails(int _empid)
        {

            SearchCls = EmpList.Where(x => x.EmpNo == _empid).Single();

        }


        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

    }

کدها در این قسمت به صورت زیر تشریح می شوند.

    1.  در  ViewModel باید رابطی برای اطلاع رسانی به کاربر هنگام تغییرات در ویژگی ها پیاده سازی شود.

    2. متد  RaisePropertyChanged  از رابط INotifyPropertyChanged پیاده سازی شود.

    3. متد RaisePropertyChanged در روند Set   از همه ویزگی ها که به کنترل ها اتصال داده شده اند  فراخوانی شود.

        برای مثال :

RaisePropertyChanged("EmpId"); //Pass the Property name as parameter 

    4. در روند ویژگی  Set از  EmpId ، یک_empid   به متد PopulateEmpDetails ارسال میشود.

private int _empid;
        public int EmpId
        {
            get
            {
                return _empid;

            }

            set
            {
                _empid = value;

                RaisePropertyChanged("EmpId");
                PopulteEmpDetails(_empid);
            }


        }

    5. متد  PopulteEmpDetails اطلاعات کارمندان را از لیست جستجو میکند و آیتم مورد نظر را به کلاس SearchCls نسبت میدهد.

private void PopulteEmpDetails(int _empid)
        {

            SearchCls = EmpList.Where(x => x.EmpNo == _empid).Single();

        }

در روند   Setاز ویژگی SearchCls ، مقدار را به شیء _searchcls نسبت می دهیم. کارمندان جستجو شده را در یک شیء از کلاس EmpCls ذخیره میکنیم.

خروجی به صورت زیر خواهد بود.

 

 

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان
  • WPF
  • 2k بازدید
  • 4 تشکر

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید