WPF框架MVVM简单例子

时间:2022-09-28 22:40:34

MVVM是Model-View-ViewModel的缩写形式,它通常被用于WPF或Silverlight开发。
Model——可以理解为带有字段,属性的类。
View——可以理解为我们所看到的UI。
View Model在View和Model之间,起到连接的作用,并且使得View和Model层分离。View Model不仅仅是Model的包装,它还包含了程序逻辑,以及Model扩展,例如,如果Model中有一个公开属性不需要在UI上显示,此时我们可以不再View Model中去定义它。

在MVVM中,VM的地位可以说是举足轻重。使用MVVM模式具有以下几个特点:
视图的cs文件包括极少的代码,其核心逻辑都被放在View Model类中,从而使得程序逻辑与视图耦合度降低。
ViewModel类作为View的DataContext。
在MVVM下,所有的事件和动作都被当成命令,如按钮的点击操作,此时不是触发点击事件,而是绑定到一个点击命令,再由命令去执行对应的逻辑。

namespace WpfApplication1
{
//第一步:自然是数据部分了,即Model层的实现。在这里定义了一个Person类,其中包含了2个基本的属性。
public class PersonModel
{
public string Name { get; set; }
public int Age { get; set; }
}
}
namespace WpfApplication1
{
//为了进行测试,下面创建一个静态方法来获得测试数据。
public class PersonDataHelper
{
public static ObservableCollection<PersonModel> GetPersons()
{
ObservableCollection<PersonModel> samplePersons = new ObservableCollection<PersonModel>();
samplePersons.Add(new PersonModel() { Name = "张三", Age = });
samplePersons.Add(new PersonModel() { Name = "王五", Age = });
samplePersons.Add(new PersonModel() { Name = "李四", Age = });
samplePersons.Add(new PersonModel() { Name = "LearningHard", Age = });
return samplePersons;
}
}
}
namespace WpfApplication1
{
//第二步:实现ViewModel层,实现数据和界面之间的逻辑。在视图模型类中,包含了属性和命令,
//因为在MVVM中,事件都当成命令来进行处理,其中命令只能与具有Command属性的控件进行绑定。
//既然要包含命令,首先就需要实现一个命令,这里自定义的命令需要实现ICommand接口。
//这里我们定义了一个QueryCommand。具体的实现代码如下所示:
public class QueryCommand : ICommand
{
#region Fields
private Action _execute;
private Func<bool> _canExecute;
#endregion public QueryCommand(Action execute)
: this(execute, null)
{
} public QueryCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
} #region ICommand Member public event EventHandler CanExecuteChanged
{
add
{
if (_canExecute != null)
{
CommandManager.RequerySuggested += value;
}
}
remove
{
if (_canExecute != null)
{
CommandManager.RequerySuggested -= value;
}
}
} public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute();
} public void Execute(object parameter)
{
_execute();
}
#endregion
}
}
    public class PersonListViewModel : INotifyPropertyChanged
{
#region Fields
private string _searchText;
private ObservableCollection<PersonModel> _resultList;
#endregion #region Properties public ObservableCollection<PersonModel> PersonList { get; private set; } // 查询关键字
public string SearchText
{
get { return _searchText; }
set
{
_searchText = value;
RaisePropertyChanged("SearchText");
}
} // 查询结果
public ObservableCollection<PersonModel> ResultList
{
get { return _resultList; }
set
{
_resultList = value;
RaisePropertyChanged("ResultList");
}
} public ICommand QueryCommand
{
get { return new QueryCommand(Searching, CanSearching); }
} #endregion #region Construction
public PersonListViewModel()
{
PersonList = PersonDataHelper.GetPersons();
_resultList = PersonList;
} #endregion #region Command Handler
public void Searching()
{
ObservableCollection<PersonModel> personList = null;
if (string.IsNullOrWhiteSpace(SearchText))
{
ResultList = PersonList;
}
else
{
personList = new ObservableCollection<PersonModel>();
foreach (PersonModel p in PersonList)
{
if (p.Name.Contains(SearchText))
{
personList.Add(p);
}
}
if (personList != null)
{
ResultList = personList;
}
}
} public bool CanSearching()
{
return true;
} #endregion #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; #endregion #region Methods
private void RaisePropertyChanged(string propertyName)
{
// take a copy to prevent thread issues
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
<Window x:Class="WpfApplication1.PersonsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="PersonsView" Height="300" Width="300">
<Window.DataContext>
<local:PersonListViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Name="searchtxt" Text="{Binding Path=SearchText, Mode=TwoWay}" HorizontalAlignment="Left" Height="30" Width="280" Margin="10,0,0,0"></TextBox>
<Button Grid.Row="0" Name="searchBtn" Content="Search" Command="{Binding Path=QueryCommand}" Width="80" Height="30" HorizontalAlignment="Right" Margin="0,0,10,0"></Button>
<DataGrid Grid.Row="1" Name="datGrid"
HorizontalAlignment="Center"
VerticalAlignment="Top" ItemsSource="{Binding Path=ResultList}" Width="300"></DataGrid>
</Grid>
</Window>

WPF框架MVVM简单例子的更多相关文章

  1. JS框架avalon简单例子 行编辑 添加 修改 删除 验证

    为什么要写这个例子:做表单的时候,表单包含主子表,对于子表的编辑,使用的是easyui datagrid的行编辑功能,由于业务比较复杂,实现起来比较麻烦,代码写的也很多,因为插件的封装,无法操作原始的 ...

  2. Jquery如何序列化form表单数据为JSON对象 C&num; ADO&period;NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request&period;Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C&num;语言描述)

    jquery提供的serialize方法能够实现. $("#searchForm").serialize();但是,观察输出的信息,发现serialize()方法做的是将表单中的数 ...

  3. 【我们一起写框架】MVVM的WPF框架(五)—完结篇

    前言 这篇文章是WPF框架系列的最后一篇,在这里我想阐述一下我对框架设计的理解. 我对框架设计的理解是这样的: 框架设计不应该局限于任何一种设计模式,我们在设计框架时,应该将设计模式揉碎,再重组:这样 ...

  4. 【我们一起写框架】MVVM的WPF框架(四)—DataGrid

    前言 这个框架写到这里,应该有很多同学发现,框架很多地方的细节,其实是违背了MVVM的设计逻辑的. 没错,它的确是违背了. 但为什么明知道违背设计逻辑,还要这样编写框架呢? 那是因为,我们编写的是框架 ...

  5. WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍

    WPF自学入门(十一)WPF MVVM模式Command命令   在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式 ...

  6. WPF自学入门(十)WPF MVVM简单介绍

     前面文章中,我们已经知道,WPF技术的主要特点是数据驱动UI,所以在使用WPF技术开发的过程中是以数据为核心的,WPF提供了数据绑定机制,当数据发生变化时,WPF会自动发出通知去更新UI. 我们不管 ...

  7. 从0到1:使用Caliburn&period;Micro&lpar;WPF和MVVM&rpar;开发简单的计算器

    从0到1:使用Caliburn.Micro(WPF和MVVM)开发简单的计算器 之前时间一直在使用Caliburn.Micro这种应用了MVVM模式的WPF框架做开发,是时候总结一下了. Calibu ...

  8. 【我们一起写框架】MVVM的WPF框架(一)—序篇

    前言 我想,有一部分程序员应该是在二三线城市的,虽然不知道占比,但想来应该不在少数. 我是这部分人群中的一份子. 我们这群人,面对的客户,大多是国内中小企业,或者*的小部门.这类客户的特点是,资金有 ...

  9. 【我们一起写框架】MVVM的WPF框架(二)—绑定

    MVVM的特点之一是实现数据同步,即,前台页面修改了数据,后台的数据会同步更新. 上一篇我们已经一起编写了框架的基础结构,并且实现了ViewModel反向控制Xaml窗体. 那么现在就要开始实现数据同 ...

随机推荐

  1. java开发人员,最应该学习和熟练使用的工具类。google guava&period;&lpar;谷歌 瓜娃&rpar;

    学习参考文章: http://blog.csdn.net/wisgood/article/details/13297535 http://ifeve.com/google-guava/ http:// ...

  2. Windows7 安装vs2015 之后 调试Web项目IIS启动不了 aspnetcore&period;dll未能加载

    安装windows企业版,整整折腾了两天了,一个本身家里网络环境不好,时不时掉线,终于披荆斩棘,克服了所有困难,结果VS2015 EnterPrise 版本在调试Web环境的时候,始终在任务栏里找不到 ...

  3. 设计模式 Mixin &lpar;混入类&rpar;

    混入(mix-in)类代表类之间的另一种关系.在C++中,混入类的语法类似于多重继承,但是语义完全不同.混入类回答"这个类还可以做什么"这个问题,答案经常以"-able& ...

  4. Chrome debug tooltip having scrollbars

    谷歌浏览器debugger,查看变量值,出现滚动条无法查看到具体的值 I had the same problem and found your post. I went as far as rein ...

  5. Java ORM Hibernate 入门笔记

    一.下载 官网地址:http://hibernate.org/ Hibernate下有ORM(关系型数据库).OGM(NoSQL数据库).Search(对象全文检索).Validator的工具. OR ...

  6. caffe服务器搭建血泪记录

    装过很多次caffe了,但这个还是遇到了很多奇葩问题,不过以前都是在ubuntu上,这次是在centos上. 1.import error  _caffe.so: undefined symbol: ...

  7. 【SparkStreaming学习之三】 SparkStreaming和kafka整合

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 scala-2.10.4(依赖jdk1.8) spark ...

  8. 【转】Android hdpi ldpi mdpi xhdpi xxhdpi适配详解

    1.了解几个概念(1)分辨率.分辨率就是手机屏幕的像素点数,一般描述成屏幕的“宽×高”,安卓手机屏幕常见的分辨率有480×800.720×1280.1080×1920等.720×1280表示此屏幕在宽 ...

  9. Cocos2d-x中文显示乱码

    Cocos2d-x 引擎编码格式默认为utf8,而VS开发环境默认为gbk2312,所以把代码文件保存为utf8格式就能解决. VS->文件->高级保存选项->Unicode(UTF ...

  10. 深度学习入门之Mnist

    参看Deep learning from scratch,学习到反向传播网络后,把网络调通了,但是训练后损失函数减小,准确率没有变化,和瞎猜一样,是为什么呢?只有在看看各层缺少什么,关键是我的参数和书 ...