[MVVM]05-MvvmLight頁面與Model層的互動含UI執行緒
阿新 • • 發佈:2019-02-06
MvvmLight頁面與Model層的互動含UI執行緒
場景
- 頁面初始化顯示model層的資訊,並且可以通過ViewModel更改相應的資訊後及時在View上顯示
操作
- 新增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>
- 新增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";
}
});
});
}
}
- 新增Dispatcherhelp,這個類是框架會自動把某個UI要做的事情委託給對應的UI,統一了呼叫方式,不用在程式碼中指定用那個UI的執行緒來更新,因為大多數時候很多人喜歡用Dispath.invoke(action)這種方式,這種會造成整個視窗的卡,所以一定要了解WPF的UI執行緒和其它工作執行緒的關係以及委託方式。
public App()
{
DispatcherHelper.Initialize();
}
- 關聯與前面的視窗一樣就是指定Datacontext
SimpleIoc.Default.Register<Window2ViewModel>();
public Window2ViewModel View2
{
get
{
return ServiceLocator.Current.GetInstance<Window2ViewModel>();
}
}
- 這裡是我喜歡的方式,其它方式可以參考同頁面傳遞訊息的文章
DataContext="{Binding Source={StaticResource Locator},Path=View2}"
提示
- model不僅僅是物件,可以是資料庫等各種資料來源與之互動,可以想到用ORM框架來建立合造的model關係對映
- 一定要注意UI執行緒要做的操作,有可能資訊沒有及時在頁面是更新很有可能是uI執行緒出了問題
- 瞭解框架的封裝和WPF自帶的處理要求可能有助於理解框架,同樣可以參看原始碼
- mvvm的框架很多,這個只是其中之一,後面我們會講到mvvm的原理,這樣對框架可以達到通一而知其它
原始碼
學習是一個很有成就感的事件,可是總結是更有意義的事件。最近一段時間要不寫wpf了,做個總結以防忘記,話說最近一段的時間的wpf全是winform那樣基於事件的。很多的程式碼都是控制顯示的感覺很不好。這裡也是推廣一下,你可以不用框架,但是一定要用wpf繫結這是它的優點。