三、Silverlight中使用MVVM(三)——进阶
这篇主要引申出Command结合MVVM模式在应用程序中的使用
我们要做出的效果是这样的

就是提供了一个简单的查询功能将结果绑定到DataGrid中,在前面的基础上,这个部分相对比较容易实现了
我们在PageViewModel中添加两个属性
private string _searchText;
//查询关键字
public string SearchText
{
get { return _searchText; }
set { _searchText = value;
if (PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs("SearchText"));
}
}
}
private List<Person> _resultText;
//查询结果
public List<Person> ResultText
{
get { return _resultText; }
set { _resultText = value;
if (PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs("ResultText"));
}
}
}
这两个属性我们后面将绑定到View中,下面实现查询方法
//查询方法
public void Searhing()
{
List<Person> person = null;
if (!string.IsNullOrEmpty(SearchText))
{
person = new List<Person>();
foreach (Person p in Human)
{
if (p.name.Contains(SearchText))
{
person.Add(p);
}
}
}
if (person != null)
{
ResultText = person;
}
}
我们这里就是通过查询到的集合person赋值给查询结果,这两步比较好理解,然后我们需要在ViewModel中声明一个Command对象来执行页面的单击事件
private ICommand _cmd;
//声明Command
public ICommand Cmd
{
get { return _cmd; }
}
public PageViewModel()
{
Human = new List<Person>();
Human = new Persons().getPerson();
_cmd = new QueryCommand(this);
}
在构造函数中实例了Command对象,在这里我们仍然有一步工作需要完成,就是对QueryCommand的实现
public class QueryCommand:ICommand
{
public PageViewModel _pageVM = null;
public QueryCommand(PageViewModel vm)
{
_pageVM = vm;
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged
{
add { }
remove { }
}
public void Execute(object parameter)
{
_pageVM.Searhing();
}
}
你可以看出来Command类是用ViewModel来实例的,自然这里面由Execute()完成查询这个工作。
最后我们将UI上做点小小的变动
<data:DataGrid ItemsSource="{Binding ResultText}" Height="200" HorizontalAlignment="Left" Margin="12,88,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="200" />
<TextBox Height="23" Text="{Binding SearchText,Mode=TwoWay}" HorizontalAlignment="Left" Margin="12,46,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
<Button Content="查询" Height="23" HorizontalAlignment="Left" Margin="137,46,0,0" Name="btnSearch" VerticalAlignment="Top" Width="75" />
我们将DataGrid的ItemSource属性绑定到ResultText上,对于输入框我们则将其绑定到SearchText属性上,这样我们就完成了大部分的工作
下面就是将View和ViewModel两者之间如何关联了,因为Sl3中不支持Commnad这个属性,所以这里我们就在后台进行声明
PageViewModel pageviewmodel=new PageViewModel();
public PageView()
{
InitializeComponent();
this.btnSearch.Click += new RoutedEventHandler(btnSearch_Click);
this.DataContext =pageviewmodel;
}
void btnSearch_Click(object sender, RoutedEventArgs e)
{
pageviewmodel.SearchText = this.textBox1.Text.Trim();
pageviewmodel.Cmd.Execute(null);
}
这一步完成后,我们就实现了开头的功能,这个功能虽然实现了,但是你可能会发现一个问题,我们将Searching()的执行写在了QueryCommand.Execute()中,
在这种情况下我们需要为每一个方法声明一个Command类,自然这不是我们期望做的事情,所以我们下面将这个问题优化一下:
我们先声明一个RelayCommand类
public class RelayCommand : ICommand
{
private Action _handler;
public RelayCommand(Action handler)
{
_handler = handler;
}
private bool _isEnabled;
public bool IsEnabled
{
get { return _isEnabled; }
set
{
if (value != _isEnabled)
{
_isEnabled = value;
if (CanExecuteChanged != null)
{
CanExecuteChanged(this, EventArgs.Empty);
}
}
}
}
public bool CanExecute(object parameter)
{
return IsEnabled;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_handler();
}
这里RelayCommand类可以作为一个派生类用于与页面Command的实现,那么ViewModel中,我们声明一个ICommand属性
private readonly ICommand _searchCommand;
public ICommand SearchCommand
{
get { return _searchCommand; }
}
自然我们需要将构造函数变动一下
public PageViewModel()
{
Human = new List<Person>();
Human = new Persons().getPerson();
_searchCommand = new RelayCommand(Searhing) { IsEnabled = true };
}
通过第3行代码,我们其实就是将ViewModel与Command分离了,最后我们将button事件代码修改一下
void btnSearch_Click(object sender, RoutedEventArgs e)
{
pageviewmodel.SearchText = this.textBox1.Text.Trim();
pageviewmodel.SearchCommand.Execute(null);
}
可能有些人不明白Command,下面对ViewModel中的Command做一下详解
在ViewModel中,使用了DelegateCommand这个实现了Icommand的泛型类,该类接收两个Icommand接口要实现的方法。
在Silverlight中,控件通常使用事件来执行一个方法。但是Silverlight提供了另一种机制,
使用的是设计模式中的Command模式,为控件提供了Command和CommandParameter属性。
Command是在WPF中被引入的,提供了松散的事件处理机制,这种模式使得事件处理代码不一定与控件紧密耦合
,Command和CommandParameter属性定义在ButtonBase类中,
它接收实现了ICommand接口的对象。在Silverlight中,
可以使用InvokeCommandAction控件来为其他的控件指定响应事件要执行的命令。
ICommand接口有3个必须实现的成员:Execute()方法在命令被调用时触发,
对于那些有Command属性的控件来说,单击控件是触发命令的唯一方式,
当然还可以使用InvokeCommandAction控件进行进一步的调用Execute()方法。
Execute()方法接收一个object类型的参数,这个参数的值放在调用控件的CommandParameter属性中,如果没有设置,该值为null。
CanExecute()方法,该方法返回true时命令才会被调用,
依赖于CommandParameter或者其他原因,可以通过在该函数中设置是否要执行方法的条件。
CanExecuteChanged事件在每次CanExecute()方法改变时会被触发。
比如CanExeucte的值依赖于object的属性,当属性改变时,
CanExecuteChanged事件必须被手动触发以通知用户界面,
CanExecute必须被重新查询,相应地控件的Enabled/Disabled也会发生改变。
除了使用DelegateCommand类外,开发人员也可以直接创建实现ICommand接口的类来供UI层进行绑定,
不过这样的做法没有使用DelegateCommand这么简洁。因此建议各位使用DelegateCommand类来实现对命令的定义。
下篇我将结合MVVM与Command实现一个简单的CRUD操作
三、Silverlight中使用MVVM(三)——进阶的更多相关文章
- Silverlight中使用MVVM(3)—进阶
这篇主要引申出Command结合MVVM模式在应用程序中的使用 我们要做出的效果是这样的 就是提供了一个简单的查询功能将结果绑定到DataGrid中,在前面的基础上,这个部分相对比较容易实现了 我们在 ...
- Silverlight中使用MVVM(1)--基础
Silverlight中使用MVVM(1)--基础 Silverlight中使用MVVM(2)—提高 Silverlight中使用MVVM(3)—进阶 Silverlight中使用MVVM(4)—演练 ...
- Silverlight中使用MVVM(4)
Silverlight中使用MVVM(1)--基础 Silverlight中使用MVVM(2)—提高 Silverlight中使用MVVM(3)—进阶 Silverlight中使用MVVM(4)—演练 ...
- Silverlight中使用MVVM(3)
Silverlight中使用MVVM(1)--基础 Silverlight中使用MVVM(2)—提高 Silverlight中使用MVVM(3)—进阶 Silverlight中使用MVVM(4)—演练 ...
- Silverlight中使用MVVM(2)
Silverlight中使用MVVM(1)--基础 Silverlight中使用MVVM(2)—提高 Silverlight中使用MVVM(3)—进阶 Silverlight中使用MVVM(4)—演练 ...
- Silverlight中使用MVVM(1)
Silverlight中使用MVVM(1) Silverlight中使用MVVM(1)--基础 Silverlight中使用MVVM(2)—提高 Silverlight中使用MVVM(3)—进阶 ...
- Silverlight中在MVVM模式下对DatagridRow选择控件封装
在项目中,凡是涉及到表格的地方用的最多的控件,自然少不了DataGrid的身影,它明了的展示各种数据让人十分喜欢.现在要实现一个功能,使DataGrid具有全选和项选中的功能,如果在传统后台代码中完成 ...
- Silverlight中使用MVVM(2)-(提高)
在第一篇文章中的示例中,我们已经简单的了解了应用MVVM模式的流程,我的本意是你已经了解了一点MVVM的概念,然后又没有一个较好的例子学习,可以跟着我一起学习MVVM模式,所以这个部分,都是没有理论知 ...
- 二、Silverlight中使用MVVM(二)——提高
在第一篇文章中的示例中,我们已经简单的了解了应用MVVM模式的流程,我的本意是你已经了解了一点MVVM的概念,然后又没有一个较好的例子学习,可以跟着我一起学习MVVM模式,所以这个部分,都是没有理论知 ...
随机推荐
- 【BZOJ1874】取石子游戏(SG函数)
题意:小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子, 每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作, 他想问你他是否有必 ...
- 【CF1073A】Diverse Substring(签到)
题意:给定一个由小写字母组成的串,要求找出一个子串使得其中出现最多的字母不超过它长度的一半下取整 n<=1e3 思路: #include<cstdio> #include<cs ...
- selenium入门教程c#
一. 简述 1. 介绍 Selenium是ThoughtWorks专门为Web应用程序编写的一个验收测试工具. Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE. ...
- C#数组排序以及比较对象的大小
先来看个小例子吧 ,,,,,}; Array.Sort(intArray); Array.ForEach<int>(intArray,(i)=>Console.WriteLine(i ...
- HDU5032 Always Cook Mushroom(树状数组&&离线)
树状数组+询问离线.一个优化是需要的,就是先对1000*1000个点先排序,而不是每次都生成这1000*1000个点然后和询问一起排序,那样会tle. #include <iostream> ...
- ASP.NET MVC 实现 AJAX 跨域请求
ASP.NET MVC 实现AJAX跨域请求的两种方法 和大家分享下Ajax 跨域的经验,之前也找了好多资料,但是都不行,后来看到个可行的修改了并测试下 果然OK了 希望对大家有所帮助! 通常发送 ...
- Write a function that generates one of 3 numbers according to given probabilities
You are given a function rand(a, b) which generates equiprobable random numbers between [a, b] inclu ...
- CSS:水平居中与垂直居中
CSS居中算是一个比较基础的问题,在实际运用中,需要考虑到的一般是两种情况,一种是主要是表现为文字,图片等行内元素的居中,一种是指 div 等块级标签元素的居中. 水平居中 1.行内元素 行内元素(主 ...
- Oracle数据库搭建
- java 相关软件使用趋势
http://www.baeldung.com/java-in-2017 https://mp.weixin.qq.com/s?__biz=MzI4NjYwMjcxOQ==&mid=224 ...