title: '[MVVM]05-MvvmLight页面与Model层的交互含UI线程 ’
date: 2017-11-26 11:02:52
tags:
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绑定这是它的优点。