1. 程式人生 > >[MVVM]05-MvvmLight頁面與Model層的互動含UI執行緒

[MVVM]05-MvvmLight頁面與Model層的互動含UI執行緒

MvvmLight頁面與Model層的互動含UI執行緒

場景

  • 頁面初始化顯示model層的資訊,並且可以通過ViewModel更改相應的資訊後及時在View上顯示

操作

  1. 新增windows.xaml並新增對應的ViewModel並建立關聯
 <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"> <TextBlock Text="{Binding Teacher.Name}"></TextBlock> <TextBlock Text="{Binding Teacher.Age}"></TextBlock> <ListView ItemsSource="{Binding Teacher.Students}"> <ListView.View
>
<GridView> <GridViewColumn Header="姓名" DisplayMemberBinding="{Binding Name}" ></GridViewColumn> <GridViewColumn Header="年齡" DisplayMemberBinding="{Binding Age}"></GridViewColumn> </GridView
>
</ListView.View> </ListView> </StackPanel> <StackPanel Grid.Column="1"> <Button Content="改變教師名稱" Command="{Binding ChangeTeacherNameCommand}"></Button> <Button Content="增加學生" Command="{Binding AddStudentCommand}"></Button> <Button Content="改變最後一名學生名稱" Command="{Binding ChangeLastStudentNameCommand}"></Button> </StackPanel> </Grid>
  1. 新增ViewModel
 public class Window2ViewModel : ViewModelBase
    {
        private Teacher _teacher;

        public Teacher Teacher
        {
            get
            {
                return _teacher;
            }
            set
            {
                _teacher = value;
                RaisePropertyChanged(() => Teacher);
            }
        }

        public RelayCommand ChangeTeacherNameCommand
        {
            get; set;
        }

        public RelayCommand AddStudentCommand
        {
            get; set;
        }

        public RelayCommand ChangeLastStudentNameCommand
        {
            get; set;
        }
        public Window2ViewModel()
        {
            Teacher = new Teacher()
            {
                Name = "LaoZhao",
                Age = 30,
                Students = new ObservableCollection<Student>()
            {
                new Student()
                {
                    Name="LaoZhange",
                    Age = 18
                }
            }
            };

            InitCommand();
        }
        private void InitCommand()
        {
            ChangeTeacherNameCommand = new RelayCommand(() =>
            {
                Task.Factory.StartNew(() =>
                {
                    Teacher.Name = "MaYun";
                });
            });

            //AddStudentCommand = new RelayCommand(() =>
            //{
            //    Task.Factory.StartNew(() =>
            //    {
            //        Teacher.Students.Add(new Student()
            //        {
            //            Name = "LaoLi",
            //            Age = 25
            //        });
            //    });
            //});
            AddStudentCommand = new RelayCommand(() =>
            {
                Task.Factory.StartNew(() =>
                {
                    DispatcherHelper.CheckBeginInvokeOnUI(() =>
                    {
                        Teacher.Students.Add(new Student()
                        {
                            Name = "LaoLi",
                            Age = 25
                        });
                    });
                });
            });

            ChangeLastStudentNameCommand = new RelayCommand(() =>
            {
                Task.Factory.StartNew(() =>
                {
                    var student = Teacher.Students.LastOrDefault();

                    if (student != null)
                    {
                        student.Name = "TheLast";
                    }
                });
            });
        }
    }
  1. 新增Dispatcherhelp,這個類是框架會自動把某個UI要做的事情委託給對應的UI,統一了呼叫方式,不用在程式碼中指定用那個UI的執行緒來更新,因為大多數時候很多人喜歡用Dispath.invoke(action)這種方式,這種會造成整個視窗的卡,所以一定要了解WPF的UI執行緒和其它工作執行緒的關係以及委託方式。
 public App()
        {
            DispatcherHelper.Initialize();
        }
  1. 關聯與前面的視窗一樣就是指定Datacontext
            SimpleIoc.Default.Register<Window2ViewModel>();
 public Window2ViewModel View2
        {
            get
            {
                return ServiceLocator.Current.GetInstance<Window2ViewModel>();
            }
        }
  1. 這裡是我喜歡的方式,其它方式可以參考同頁面傳遞訊息的文章
        DataContext="{Binding Source={StaticResource Locator},Path=View2}"

提示

  • model不僅僅是物件,可以是資料庫等各種資料來源與之互動,可以想到用ORM框架來建立合造的model關係對映
  • 一定要注意UI執行緒要做的操作,有可能資訊沒有及時在頁面是更新很有可能是uI執行緒出了問題
  • 瞭解框架的封裝和WPF自帶的處理要求可能有助於理解框架,同樣可以參看原始碼
  • mvvm的框架很多,這個只是其中之一,後面我們會講到mvvm的原理,這樣對框架可以達到通一而知其它這裡寫圖片描述
    原始碼

學習是一個很有成就感的事件,可是總結是更有意義的事件。最近一段時間要不寫wpf了,做個總結以防忘記,話說最近一段的時間的wpf全是winform那樣基於事件的。很多的程式碼都是控制顯示的感覺很不好。這裡也是推廣一下,你可以不用框架,但是一定要用wpf繫結這是它的優點。