(申明:最近在做一个练习,写点东西,谨供参考。)
1、界面展示:其中的布局和样式就不说了,重点在mvvm架构和数据绑定(model层使用ef(entity framework)实体框架,不做介绍)。
绑定后:
2、架构介绍:
在views层中新建cusgroupeditwindow窗体,viewmodels中建立cusgroupeditviewmodel类,在窗体的xaml或者cs中引用viewmodels对应类:
xaml中:
c879f5c3c9893e45ba2ce7d26e997114
92c72cd9b9c57deded9b4898c5a2dbe2 1da84c50fa7328704b2ce9dda53aedda
7473f81b006ddc8e53f2d378bc7dce62
cs:datacontext = cusgroupeditviewmodel。(添加引用路径)
/***********************************************/
*csgroup是在viewmodel中定义的一个cusgroup对象, *
*cusgroup对象是在sql数据库中的表,在ef中的对象。*
/***********************************************/
3、textbox绑定:
ff1681ddee25e4aeb6879b3c67fb00b5
4、button绑定:
5d362da14155c388b940c2445466edf6
29deedf2cd939b8bccbf37085c6a617a8b6de9c7d98b148f30b5dd6899a18be9
a1cb88e6789f399807801ea3799938af
dfca9557cc388af630eeba6df35e96f8
c05eec64ed02ad0975536668a09b61b7
5、checkbox绑定:
04efaf97de328fe03fc57ff1cb705f93
456c2222d60e5b20af2a55c567b254f7 6、combobox绑定:
6、combobox绑定:
<combobox maxwidth="150" width="100" selectedvalue="{binding strcmbselectvalue, mode=twoway, updatesourcetrigger=propertychanged}" displaymemberpath="text"
selectedvaluepath="value" itemssource="{binding lstcsgdownlevelid, mode=twoway,updatesourcetrigger=propertychanged}" />
<!--selectedvalue:选中commobox的值,mode双向模式,属性改变时触发;displaymemberpath:显示时绑定;selectedvaluepath:表示选择下拉框某一项对应的值;itemssource:绑定的数据源 -->
<!-- 其中value和text也可理解为数据源,在viewmodel中有赋值-->
7、datagrid绑定:
<datagrid columnwidth="*" selecteditem="{binding currentselectitem}" itemssource="{binding csgroupsall}" autogeneratecolumns="false" isreadonly="true" >
<datagrid.columns>
<datagridtextcolumn header="分组编号" binding="{binding code}" />
<datagridtextcolumn header="分组名称" binding="{binding name}" />
</datagrid.columns>
</datagrid>
/***************************************************************/
//datagrid当前选择对象private cusgroup currentselectitem;public cusgroup currentselectitem
{get { return currentselectitem; }set{
currentselectitem = value;
getcutcmbselect(value);
}
}
view code
<!--代码没有自动缩进,有点不知所措-->
/***************************************************************/
viewmodel 中的代码:
using heyin.erp.datamodels;using heyin.erp.iservices;using heyin.erp.models;using heyin.erp.services;using microsoft.practices.prism.commands;using system;using system.collections.generic;using system.collections.objectmodel;using system.windows;using system.text.regularexpressions;using system.windows.controls;namespace heyin.erp.client.viewmodels.customer
{class cusgroupeditviewmodel : baseviewmodel
{private bool bisadd = false;
icusgroupservice cgs; //调用iservice接口#region properties 属性private guid gcsgroupid = guid.empty;//all cusgroupprivate list<cusgroup> csgroupsall;public list<cusgroup> csgroupsall
{get { return csgroupsall; }set{
csgroupsall = value; //设定值onpropertychanged("csgroupsall"); //在属性更改后,通知 }
}private list<cusgroup> csgroupsminprestore;public list<cusgroup> csgroupsallminprestore
{get { return csgroupsminprestore; }set{
csgroupsminprestore = value; //设定值onpropertychanged("csgroupsallminprestore"); //在属性更改后,通知 }
}//cusgroup对象private cusgroup csgroup;public cusgroup csgroup
{get { return csgroup; }set{ csgroup = value;
onpropertychanged("csgroup"); }
}/// <summary>/// /// </summary>private string strcmbselectvalue;public string strcmbselectvalue
{get { return strcmbselectvalue; }set{if (value != null)
{
strcmbselectvalue = value;
onpropertychanged("strcmbselectvalue");
}
}
}/// <summary>/// comboboxdatamodel:作为一个combobox的对象,可以理解为数据源/// </summary>private observablecollection<comboboxdatamodel> lstcsgdownlevelid;public observablecollection<comboboxdatamodel> lstcsgdownlevelid
{get { return lstcsgdownlevelid; }set{
lstcsgdownlevelid = value;
onpropertychanged("lstcsgdownlevelid");
}
}//datagrid当前选择对象private cusgroup currentselectitem;public cusgroup currentselectitem
{get { return currentselectitem; }set{
currentselectitem = value;
getcutcmbselect(value);
}
}private int errorcount;public int errorcount { get => errorcount; set => errorcount = value; }#endregion#region commandspublic delegatecommand<string> btnchangedcommand { get; set; }public delegatecommand<cusgroup> txtchangedcommand { get; set; } #endregionpublic cusgroupeditviewmodel()
{
cgs = new cusgroupservice();
csgroupsall = new list<cusgroup>();
csgroup = new cusgroup();
lstcsgdownlevelid = new observablecollection<comboboxdatamodel>();
btnchangedcommand = new delegatecommand<string>(menuclick);
txtchangedcommand = new delegatecommand<cusgroup>(changecmbvalue);
getallcusgroups();
}#region buttonclickprivate void menuclick(string strmessage)
{if (string.isnullorempty(strmessage)) return;if (csgroup == null) return;switch (strmessage)
{case "btncusgroupsave":
save();break;case "btncusgroupadd":
add();break;case "btncusgroupdelete":
delete();break;
}
}#endregion buttonclick#region motheds/// <summary>/// 获取全部group/// </summary>private void getallcusgroups()
{//获取满足条件的客户分组信息 csgroupsall.clear();
csgroupsall = cgs.get(s => s.isdelete == 0);
getallcmbitems();//给降档分组下拉框赋值if ((gcsgroupid == null || gcsgroupid == guid.empty) && csgroupsall.count > 0)
csgroup = csgroupsall[0]; //给基础信息等赋值strcmbselectvalue = csgroup.downlevelid.tostring();//设置降档分组默认值 }/// <summary>/// 添加/// </summary>/// <param name="cg"></param>private void addcusgroup(cusgroup cg)
{
cg.id = guid.newguid(); //新建分组guidcg.isdelete = 0; //默认为0:不删除cg.createby = app.getcurrentuserid();//创建人员关联员工 guidcg.createtime = datetime.now; //初始化创建时间,应该使用服务器当前时间bool c = cgs.add(cg);if (c)
{
messagebox.show(string.format("创建新组别【{0}】成功!", csgroup.name), "提示", messageboxbutton.ok, messageboximage.information);
getallcusgroups();
bisadd = false;
}
}/// <summary>/// 修改/// </summary>/// <param name="cg"></param>private void updatecusgroup(cusgroup cg)
{
bisadd = false;
cg.updatetime = datetime.now;
cg.updateby = app.getcurrentuserid();//更新人员关联员工 guidstring[] str = { "updatetime", "updateby" };bool b = cgs.edit(cg, str);if (b)
{
messagebox.show("更改组别【成功】!", "提示", messageboxbutton.ok, messageboximage.information);
getallcusgroups();
}
}/// <summary>///删除方法(实为更新)/// </summary>/// <param name="cg"></param>private void deletecusgroup(cusgroup cg)
{
cg.isdelete = 1; //更改数据库删除标志cg.updatetime = datetime.now; //更新删除时间cg.updateby = app.getcurrentuserid();//更新人员关联员工 guidstring[] str = { "updatetime", "isdelete", "updateby" };bool b = cgs.edit(cg, str);if (b)
{//messagebox.show(string.format("已删除组别【{0}】!", csgroup.name), "提示", messageboxbutton.ok, messageboximage.information); getallcusgroups();
csgroup = new cusgroup(); //清空对象bisadd = true;
}
}/// <summary>/// 插入和更新方法调用/// </summary>private void save()
{if (errorcount > 0)
{//判断必填数据是否为空:为空则提示messagebox.show("请核对所填数据", "提示", messageboxbutton.yesno, messageboximage.information);return;
}if (bisadd)
addcusgroup(csgroup);elseupdatecusgroup(csgroup);
}/// <summary>/// 获取降档分组下拉列表的值,并指定默认值/// </summary>/// <param name="value"></param>private void getcutcmbselect(cusgroup value)
{
bisadd = false;//点击新增后,再选择列表的逻辑if (value != null)
{
csgroup = cgs.getbyid(value.id);//查找出当前选中的对象gcsgroupid = csgroup.id; //保存当前选择对象的guidif (csgroup != null)
{if (csgroup.downlevelid.hasvalue)
{//如果降档id有值,则默认显示,如果没有,则显示为空getexceptcmbselect();//刷新下拉列表,先刷新,再赋值给默认值strcmbselectvalue = csgroup.downlevelid.tostring();
}else{
lstcsgdownlevelid.clear();
strcmbselectvalue = string.empty;
}
}
}
}private void add()
{
bisadd = true;//点击新建分组时,重新获取所有降档id对应的中文名 getallcmbitems();
csgroup = new cusgroup();
}private void delete()
{if (this.csgroup.id == guid.empty || csgroup.id == null)
messagebox.show("请选择要删除组别", "提示", messageboxbutton.ok, messageboximage.information);else{
messageboxresult msgresult = messagebox.show(string.format("确定要删除分组【{0}】吗?", csgroup.name), "提示", messageboxbutton.yesno, messageboximage.information);if (msgresult == messageboxresult.yes)
deletecusgroup(csgroup);
}
}/// <summary>/// 排除当前列的降档id和对应的name/// </summary>private void getexceptcmbselect()
{
lstcsgdownlevelid.clear();
csgroupsallminprestore = cgs.get(s => s.isdelete == 0 && s.minprestore <= csgroup.minprestore);foreach (var idlid in csgroupsallminprestore)
{if (idlid.id != csgroup.id) //去除当前选择id对应的namelstcsgdownlevelid.add(new comboboxdatamodel() { value = idlid.id.tostring(), text = idlid.name });
}
}/// <summary>/// 获取列表中所有降档id和对应的name/// </summary>private void getallcmbitems()
{
lstcsgdownlevelid.clear();foreach (var idlid in csgroupsall)
{
lstcsgdownlevelid.add(new comboboxdatamodel() { value = idlid.id.tostring(), text = idlid.name });
}
}private void changecmbvalue(cusgroup cgminprestore)
{
lstcsgdownlevelid.clear();
list<cusgroup> lsttextchange = new list<cusgroup>();
lsttextchange = cgs.get(s => s.minprestore < cgminprestore.minprestore);foreach (var idlid in lsttextchange)
{
lstcsgdownlevelid.add(new comboboxdatamodel() { value = idlid.id.tostring(), text = idlid.name });
}
}public void sizechangedcommand(object obj, sizechangedeventargs e)
{
messagebox.show("日了狗");
}#endregion}
}
view中代码:
<client:basewindow x:class="heyin.erp.client.views.customer.cusgroupeditwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:interaction="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:interactivity="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:commonvalidation="clr-namespace:heyin.erp.common.validation;assembly=heyin.erp.common"
xmlns:client="clr-namespace:heyin.erp.client"
mc:ignorable="d"
x:name="cusgroupwindow"
title="客户分组" height="500" width="800"
windowstartuplocation="centerowner"
loaded="window_loaded"
maxboxenable="true"
minboxenable="false" >
<interactivity:interaction.triggers>
<interactivity:eventtrigger eventname="sizechanged">
<interaction:callmethodaction targetobject="{binding}" methodname="sizechangedcommand"/>
</interactivity:eventtrigger>
</interactivity:interaction.triggers>
<grid>
<grid.rowdefinitions>
<rowdefinition height="*" />
<rowdefinition height="50" />
</grid.rowdefinitions>
<grid grid.row="0">
<grid.columndefinitions>
<columndefinition width="1*"/>
<columndefinition width="2*"/>
</grid.columndefinitions>
<!-- left -->
<grid margin="5,0,5,5">
<groupbox name="gbgroupdata">
<groupbox.headertemplate>
<datatemplate>
<wrappanel margin="{staticresource wrappanelmarginforinfo}">
<textblock text="客户分组" height="20" />
<button width="20" height="20" margin="50,0,0,0"
command="{binding datacontext.btnchangedcommand,relativesource={relativesource mode=findancestor,ancestortype=groupbox}}"
commandparameter="btncusgroupadd"
visibility="{binding savevisibility,mode=twoway,updatesourcetrigger=propertychanged}">
<image source="..\..\resources\images\16\add.png" />
</button>
<button width="20" height="20" margin="10,0,0,0"
command="{binding datacontext.btnchangedcommand,relativesource={relativesource mode=findancestor,ancestortype=groupbox}}"
commandparameter="btncusgroupdelete"
visibility="{binding savevisibility,mode=twoway,updatesourcetrigger=propertychanged}">
<image source="..\..\resources\images\16\clear.png" />
</button>
</wrappanel>
</datatemplate>
</groupbox.headertemplate>
<grid>
<grid grid.row="1">
<datagrid columnwidth="*" selecteditem="{binding currentselectitem}" itemssource="{binding csgroupsall}" autogeneratecolumns="false" isreadonly="true" >
<datagrid.columns>
<datagridtextcolumn header="分组编号" binding="{binding code}" />
<datagridtextcolumn header="分组名称" binding="{binding name}" />
</datagrid.columns>
</datagrid>
</grid>
</grid>
</groupbox>
</grid>
<!-- right -->
<grid grid.column="1" margin="5">
<grid.rowdefinitions>
<rowdefinition height="*"/>
<rowdefinition height="100"/>
<rowdefinition height="130"/>
</grid.rowdefinitions>
<!-- 基础信息 -->
<grid>
<groupbox>
<groupbox.header>
<textblock text="基础信息" height="20"/>
</groupbox.header>
<stackpanel>
<grid margin="0,10">
<grid.columndefinitions>
<columndefinition width="*" />
<columndefinition width="*" />
</grid.columndefinitions>
<textbox visibility="collapsed" x:name="tberrorcount" text="{binding errorcount, mode=twoway,updatesourcetrigger=propertychanged}"></textbox>
<wrappanel margin="{staticresource wrappanelmarginforinfo}">
<textblock width="60" margin="{staticresource textblockmarginformostleft}"><run text="分组编号" /></textblock>
<textbox name="txtcusgropcrod" maxwidth="150" width="100"
tooltip="{binding relativesource={relativesource self},path=(validation.errors).currentitem.errorcontent}" validation.error="validation_error">
<textbox.text>
<binding path="csgroup.code" mode="twoway" updatesourcetrigger="propertychanged" validatesondataerrors="true" notifyonvalidationerror="true">
<binding.validationrules>
<exceptionvalidationrule></exceptionvalidationrule>
<commonvalidation:requiredvalidationrule maxlenth="15" errormessage="分组编号" isrequired="true" validatesontargetupdated="true" />
</binding.validationrules>
</binding>
</textbox.text>
</textbox>
</wrappanel>
<wrappanel margin="{staticresource wrappanelmarginforinfo}" grid.column="1">
<textblock text="分组名称" width="60" margin="{staticresource textblockmarginformostleft}"/>
<textbox name="txtcusgropname" maxwidth="150" width="100"
tooltip="{binding relativesource={relativesource self},path=(validation.errors).currentitem.errorcontent}" validation.error="validation_error">
<textbox.text>
<binding path="csgroup.name" mode="twoway" updatesourcetrigger="propertychanged" validatesondataerrors="true" notifyonvalidationerror="true">
<binding.validationrules>
<exceptionvalidationrule></exceptionvalidationrule>
<commonvalidation:requiredvalidationrule maxlenth="15" errormessage="分组名称" isrequired="true" validatesontargetupdated="true" />
</binding.validationrules>
</binding>
</textbox.text>
</textbox>
</wrappanel>
</grid>
<grid>
<wrappanel margin="{staticresource wrappanelmarginforinfo}">
<textblock margin="{staticresource textblockmarginformostleft}" width="60" verticalalignment="center"><run text="分组描述" /></textblock>
<textbox x:name="tbremark" textwrapping="wrap" acceptsreturn="true" verticalscrollbarvisibility="visible" width="400" height="90"
tooltip="{binding relativesource={relativesource self},path=(validation.errors).currentitem.errorcontent}" validation.error="validation_error">
<textbox.text>
<binding path="csgroup.description" mode="twoway" updatesourcetrigger="propertychanged" validatesondataerrors="true" notifyonvalidationerror="true">
<binding.validationrules>
<exceptionvalidationrule></exceptionvalidationrule>
<commonvalidation:requiredvalidationrule maxlenth="300" errormessage="分组描述" validatesontargetupdated="true" />
</binding.validationrules>
</binding>
</textbox.text>
</textbox>
</wrappanel>
</grid>
</stackpanel>
</groupbox>
</grid>
<!-- 消费相关 -->
<grid grid.row="1" margin="0,10,0,10">
<grid>
<groupbox>
<groupbox.header>
<textblock text="消费相关"/>
</groupbox.header>
<grid margin="0,10">
<grid.columndefinitions>
<columndefinition width="*"/>
<columndefinition width="*"/>
</grid.columndefinitions>
<wrappanel margin="{staticresource wrappanelmarginforinfo}">
<textblock text="消费积分" width="60" height="20" margin="{staticresource textblockmarginformostleft}" />
<textbox name="txtcusgropjf" maxwidth="150" width="100" text="{binding csgroup.pointconversion, mode=twoway,updatesourcetrigger=propertychanged}" />
</wrappanel>
<wrappanel grid.column="1" margin="{staticresource wrappanelmarginforinfo}" horizontalalignment="left" verticalalignment="center">
<checkbox name="cbcash" margin="0,0,5,0" ischecked="{binding csgroup.iscash}"/>
<textblock text="开通预存或储值时禁止现金交易" />
</wrappanel>
</grid>
</groupbox>
</grid>
</grid>
<!-- 预存相关 -->
<grid grid.row="2">
<groupbox>
<groupbox.header>
<textblock text="预存相关"/>
</groupbox.header>
<stackpanel>
<grid margin="0,10">
<grid.columndefinitions>
<columndefinition width="*"/>
<columndefinition width="*"/>
</grid.columndefinitions>
<wrappanel margin="{staticresource wrappanelmarginforinfo}">
<textblock width="80" margin="{staticresource textblockmarginformostleft}" ><run text="预存最低充值"/></textblock>
<textbox maxwidth="150" width="100" text="{binding csgroup.minprestore, mode=twoway,updatesourcetrigger=propertychanged}" />
</wrappanel>
<wrappanel grid.column="1" margin="{staticresource wrappanelmarginforinfo}">
<textblock width="80" text="金额低缺报警" margin="{staticresource textblockmarginformostleft}" />
<textbox maxwidth="550" width="100" text="{binding csgroup.alarm,mode=twoway}" />
</wrappanel>
</grid>
<grid margin="0,5">
<wrappanel margin="{staticresource wrappanelmarginforinfo}">
<textblock width="190" text="预存金额未达到最低要求时降档至" margin="{staticresource textblockmarginformostleft}"/>
<combobox maxwidth="150" width="100" selectedvalue="{binding strcmbselectvalue, mode=twoway, updatesourcetrigger=propertychanged}" displaymemberpath="text"
selectedvaluepath="value" itemssource="{binding lstcsgdownlevelid, mode=twoway,updatesourcetrigger=propertychanged}" />
</wrappanel>
</grid>
</stackpanel>
</groupbox>
</grid>
</grid>
</grid>
<!-- bottom -->
<grid grid.row="2">
<wrappanel horizontalalignment="center" verticalalignment="center" margin="{staticresource wrappanelmarginforinfo}">
<button margin="1" command="{binding btnchangedcommand}" commandparameter="btncusgroupsave" background="#fc8530" style="{staticresource savebuttonstyle}"
visibility="{binding savevisibility,mode=twoway,updatesourcetrigger=propertychanged}" >
<textblock text="保存" fontweight="bold" fontsize="16"></textblock>
</button>
</wrappanel>
</grid>
</grid>
</client:basewindow>
以上就是什么是mvvm架构和数据绑定?的详细内容。