抽象基礎(chǔ)資料ViewModel模板

基礎(chǔ)資料是ERP中一個模塊这敬。主要功能是相當于一個數(shù)據(jù)字典铅鲤。最近在搭建一個簡單的ERP的框架。需要將基礎(chǔ)資料與單據(jù)的模板抽象出來万牺,做成通用模板罗珍,以后需要新增基礎(chǔ)資料和單據(jù)時,只需要繼承相應的模板脚粟,增刪改查覆旱,審核、棄審核无、打印等都不需要再寫扣唱。
這篇文章主要介紹基礎(chǔ)資料的模板搭建。
我們先建一個ViewModelBase团南,添加一些常用的工具欄命令噪沙。

public partial class ViewModelBase : INotifyPropertyChanged
{
    public ViewModelBase()
    {
        CloseCommand = new DelegateCommand<T_DATAFLOWSUBOPER>(ExecuteClose);
        PrintCommand = new DelegateCommand<T_DATAFLOWSUBOPER>(ExecutePrint, CanExecutePrint);
        SaveCommand = new DelegateCommand<T_DATAFLOWSUBOPER>(ExecuteSave, CanExecuteSave);
        DeleteCommand = new DelegateCommand<T_DATAFLOWSUBOPER>(ExecuteDelete, CanExecuteDelete);
        DetailCommand = new DelegateCommand(ExecuteDetail);
        NavigateCommand = new DelegateCommand<string>(ExecuteNavigate);
        ShowHandInputCommand = new DelegateCommand(ExecuteShowHandInput);
        AddCommand = new DelegateCommand<T_DATAFLOWSUBOPER>(ExecuteAdd);
        ModifyCommand = new DelegateCommand<T_DATAFLOWSUBOPER>(ExecuteModify);
        ListCommand = new DelegateCommand<T_DATAFLOWSUBOPER>(ExecuteList);
        MouseDoubleClickCommand = new DelegateCommand(ExecuteMouseDoubleClick);
        ReferBDCommand = new DelegateCommand(ExecuteReferBD);
        ExitCommand = new DelegateCommand(ExecuteExit);
        AuditCommand = new DelegateCommand<T_DATAFLOWSUBOPER>(ExecuteAudit, CanExecuteAudit);
        UnAuditCommand = new DelegateCommand<T_DATAFLOWSUBOPER>(ExecuteUnAudit, CanExecuteUnAduti);
    } #region 【命令】
    public DelegateCommand<T_DATAFLOWSUBOPER> AddCommand { get; set; }

    /// <summary>
    /// 保存命令
    /// </summary>
    public DelegateCommand<T_DATAFLOWSUBOPER> SaveCommand { get; set; }

    /// <summary>
    /// 審核
    /// </summary>
    public DelegateCommand<T_DATAFLOWSUBOPER> AuditCommand { get; set; }

    /// <summary>
    /// 反審核
    /// </summary>
    public DelegateCommand<T_DATAFLOWSUBOPER> UnAuditCommand { get; set; }

    /// <summary>
    /// 打印命令
    /// </summary>
    public DelegateCommand<T_DATAFLOWSUBOPER> PrintCommand { get; set; }

    /// <summary>
    /// 關(guān)閉命令
    /// </summary>
    public DelegateCommand<T_DATAFLOWSUBOPER> CloseCommand { get; set; }

    /// <summary>
    /// 詳情命令
    /// </summary>
    public DelegateCommand DetailCommand { get; set; }

    /// <summary>
    /// 刪除命令
    /// </summary>
    public DelegateCommand<T_DATAFLOWSUBOPER> DeleteCommand { get; set; }

    /// <summary>
    /// 導航命令
    /// </summary>
    public DelegateCommand<string> NavigateCommand { get; set; }

    /// <summary>
    /// 手寫命令
    /// </summary>
    public DelegateCommand ShowHandInputCommand { get; set; }

    public DelegateCommand<T_DATAFLOWSUBOPER> ModifyCommand { get; set; }

    public DelegateCommand<T_DATAFLOWSUBOPER> ListCommand { get; set; }

    public DelegateCommand MouseDoubleClickCommand { get; set; }

    public DelegateCommand ReferBDCommand { get; set; }

    public DelegateCommand ExitCommand { get; set; }
    #endregion
 #region 【執(zhí)行命令】

    public virtual void ExecuteSave(T_DATAFLOWSUBOPER para)
    {
        MessageService.Show("Save");
    }

    public virtual void ExecutePrint(T_DATAFLOWSUBOPER para)
    {
        MessageService.Show("Print");
    }

    public virtual void ExecuteClose(T_DATAFLOWSUBOPER para)
    {
        Messager.Messager.Default.Send("CloseChildWindow");
    }

    public virtual void ExecuteDetail()
    {
        throw new NotImplementedException();
    }

    public virtual void ExecuteDelete(T_DATAFLOWSUBOPER para)
    {
        MessageService.Show("Delete");
    }

    public virtual void ExecuteNavigate(string obj)
    {
        throw new NotImplementedException();
    }


    public virtual void ExecuteShowHandInput()
    {
        GlobalMethod.CallHandWriting();
    }

    public virtual void ExecuteAdd(T_DATAFLOWSUBOPER para)
    {
        MessageService.Show("Add");
    }

    public virtual void ExecuteModify(T_DATAFLOWSUBOPER para)
    {
    }

    public virtual void ExecuteList(T_DATAFLOWSUBOPER para)
    {

    }

    public virtual void ExecuteMouseDoubleClick()
    {

    }

    public virtual void ExecuteReferBD()
    {
        GlobalVariableBusiness.BaseData.ReferBaseData();
    }

    public virtual void ExecuteExit()
    {
        GlobalMethod.ApplicationExit();
    }

    public virtual void ExecuteAudit(T_DATAFLOWSUBOPER para)
    {

    }
    public virtual void ExecuteUnAudit(T_DATAFLOWSUBOPER para)
    {

    }
    #endregion

    #region 【命令邏輯】

    public virtual bool CanExecuteSave(T_DATAFLOWSUBOPER para)
    {
        return true;
    }

    public virtual bool CanExecutePrint(T_DATAFLOWSUBOPER para)
    {
        return true;
    }

    protected virtual bool CanExecuteUnAduti(T_DATAFLOWSUBOPER arg)
    {
        return true;
    }

    protected virtual bool CanExecuteAudit(T_DATAFLOWSUBOPER arg)
    {
        return true;
    }


    protected virtual bool CanExecuteDelete(T_DATAFLOWSUBOPER arg)
    {
        return true;
    }
    #endregion
    #region 【實現(xiàn)接口】
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
    #endregion
}

現(xiàn)在我們增加基礎(chǔ)資料的通用ViewModel,繼承自ViewModelBase吐根,并重載命令的具體實現(xiàn)正歼。

public class BDViewModelBase<T>:ViewModelBase
{
private T _Master;
public T Master
{
get { return _Master; }
set
{
_Master = value;
RaisePropertyChanged("Master");
if (Master != null)
{
SetAuditImageShowStatus(Master.GetPropValue("FSTATUS"));
}
}
}
private List<T> _Detail;

    public List<T> Detail
    {
        get { return _Detail; }
        set { _Detail = value; RaisePropertyChanged("Detail"); }
    }
    private T _SelectedData;

    public T SelectedData
    {
        get { return _SelectedData; }
        set 
        { 
            _SelectedData = value; 
            RaisePropertyChanged("SelectedData");
            if (value != null)
            {
                Master = GlobalMethod.Clone(SelectedData);
                
            }
        }
    }
    #region 重載
    public override bool CanExecuteSave(T_DATAFLOWSUBOPER para)
    {
        if (BillState != NFMES.Core.Type.BillStateType.Complete)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public override NFMES.Core.MVVM.ViewModelBase ReferData()
    {
        ReLoadData();
        return base.ReferData();
    }
    public override void ReLoadData()
    {
        Master = Activator.CreateInstance<T>();
        Detail = BaseData.GetBaseDataList<T>();
    }
    #region 工具欄操作
    public override void ExecuteAdd(T_DATAFLOWSUBOPER para)
    {
        CanEdit = true;
        Master = Activator.CreateInstance<T>();
        BillState = NFMES.Core.Type.BillStateType.newbill;
    }
    public override void ExecuteModify(T_DATAFLOWSUBOPER para)
    {
        CanEdit = true;
        BillState = NFMES.Core.Type.BillStateType.modifybill;
    }
    public override void ExecuteSave(T_DATAFLOWSUBOPER para)
    {
        if (GlobalVariableBusiness.VaridateObj.CheckBaseDataNumberOnly(Master.GetTypeName(), Master.GetPropValue("FNUMBER").ToString())>0)
        {
            MessageService.Show("編號不可重復!");
            return;
        }
        int result = -1;
        switch (BillState)
        {
            case NFMES.Core.Type.BillStateType.newbill:
                result = BaseData.SaveBaseData<T>(Master);

                MessageService.Show(NFMES.Core.Type.OperateType.save, result);
                break;

            case NFMES.Core.Type.BillStateType.modifybill:
                result = BaseData.UpdateBaseData<T>(Master);

                MessageService.Show(NFMES.Core.Type.OperateType.update, result);
                break;
        }

        if (result >= 0)
        {
            Detail = new List<T>(BaseData.GetBaseDataList<T>());
            CanEdit = false;
            BillState = NFMES.Core.Type.BillStateType.Complete;
        }
    }

    public override void ExecuteDelete(T_DATAFLOWSUBOPER para)
    {
        if (GlobalVariableBusiness.VaridateObj.CheckBaseDataUsed(SubClass.FAddInKey, Convert.ToInt32(Master.GetPropValue("FID"))) == -1)
        {
            MessageService.Show("此條數(shù)據(jù)已被使用拷橘,不可刪除局义!");
            return;
        }
        
        int result = BaseData.DeleteBaseData<T>(Master);

        MessageService.Show(NFMES.Core.Type.OperateType.delete, result);
        if (result >= 0)
        {
            Master = Activator.CreateInstance<T>();
            Detail = new List<T>(BaseData.GetBaseDataList<T>());

        }
    }
    #endregion
    #endregion
}

可以看到,我們的BDViewModelBase需要傳遞一個泛型冗疮,我們的模板類里旭咽,都是基于這個泛型來做增刪改查的。
類中有三個屬性赌厅,Master,Detail轿塔,SelectedData特愿。MVVM模式,VM中的數(shù)據(jù)需要綁定到View中的勾缭。所以這三個數(shù)據(jù)揍障,就是我們基礎(chǔ)資料的數(shù)據(jù)源。后面加的所有基礎(chǔ)資料View俩由,綁定的數(shù)據(jù)源名稱都是相同的毒嫡。
Master是錄入部分,Detail是列表部分幻梯,SelectedData是選中的列表行數(shù)據(jù)兜畸。
數(shù)據(jù)的DAL層用的Dapper框架努释,這個這邊就不討論了。我前面的文章有個對Dapper的封裝的分享咬摇,也用在這個項目中了伐蒂。

下面,我們基礎(chǔ)資料的模板有了肛鹏。以后變動的就是基礎(chǔ)資料界面逸邦。如果基礎(chǔ)資料的界面上的字段都一樣,也可以做成通用的在扰,不過很少缕减。最常用的就是編碼、名稱字段芒珠。不過有時會關(guān)聯(lián)其它基礎(chǔ)資料桥狡。比如員工就需要關(guān)聯(lián)角色。
下面我們看看一個標準的基礎(chǔ)資料的View的寫法妓局。以部門資料為例:

<UserControl
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid" xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors" xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol" x:Class="MESClient.Unit.Depart.Depart"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<dxlc:LayoutControl VerticalAlignment="Top">
<dxlc:LayoutGroup Orientation="Vertical">
<dxlc:LayoutGroup>
<dxlc:LayoutItem Label="編號" Height="36" >
<dxe:TextEdit IsEnabled="{Binding CanEdit}" Style="{StaticResource TextEditNoBorderStyle}" Text="{Binding Master.FNUMBER,UpdateSourceTrigger=PropertyChanged}" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="名稱" Height="36" >
<dxe:TextEdit IsEnabled="{Binding CanEdit}" Style="{StaticResource TextEditNoBorderStyle}" Text="{Binding Master.FNAME,UpdateSourceTrigger=PropertyChanged}" />
</dxlc:LayoutItem>
</dxlc:LayoutGroup>
</dxlc:LayoutGroup>
</dxlc:LayoutControl>
<GridSplitter Style="{DynamicResource GridSplitterHStyle}"/>
<dxg:GridControl Style="{DynamicResource GridControlStyle}" Grid.Row="1" ItemsSource="{Binding Detail}" SelectedItem="{Binding SelectedData}">
<dxg:GridControl.Columns>
<dxg:GridColumn FieldName="FNUMBER" Header="編碼"/>
<dxg:GridColumn FieldName="FNAME" Header="名稱"/>
<dxg:GridColumn FieldName="FSTATUS" Header="單據(jù)狀態(tài)">
<dxg:GridColumn.EditSettings>
<dxe:ComboBoxEditSettings ItemsSource="{Binding StatusTypeData.BillStatusList,Mode=OneWay}" ValueMember="Id" DisplayMember="Description"/>
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
</dxg:GridControl.Columns>
<dxg:GridControl.View>
<dxg:TableView AllowEditing="False" ShowGroupPanel="False"/>
</dxg:GridControl.View>
</dxg:GridControl>
</Grid>
</UserControl>

現(xiàn)在总放,我們不需要再為部門單獨做ViewModel了,我們直接用通用的BDViewModelBase好爬。

public partial class Depart : UserControl
{
    public Depart()
        : this(null)
    {

    }

    public Depart(object para)
    {
        InitializeComponent();

        this.DataContext = new BDViewModelBase<T_Department>();
    }
}

T_Department是一個Model局雄,與數(shù)據(jù)表的結(jié)構(gòu)相同。
如果嫌寫一個與表結(jié)構(gòu)相同的Model麻煩存炮,可以參考我前面的一篇文章炬搭,利用tt模板,自動將表結(jié)構(gòu)生成Model實體。
如果我們需要增加一個職員的檔案凉驻,界面如果和部門一樣的話佩研,那我們只需要改下this.DataContext的那行代碼
this.DataContext = new BDViewModelBase<T_Employee>();
只需要換一下實體。

抽象單據(jù)的方法與此類似灼芭,只是數(shù)據(jù)源和保存刪除,數(shù)據(jù)刷新會有不同般又。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末彼绷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子茴迁,更是在濱河造成了極大的恐慌寄悯,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件堕义,死亡現(xiàn)場離奇詭異猜旬,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門洒擦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來椿争,“玉大人,你說我怎么就攤上這事秘遏∏鹧Γ” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵邦危,是天一觀的道長洋侨。 經(jīng)常有香客問我,道長倦蚪,這世上最難降的妖魔是什么希坚? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮陵且,結(jié)果婚禮上裁僧,老公的妹妹穿的比我還像新娘。我一直安慰自己慕购,他們只是感情好聊疲,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著沪悲,像睡著了一般获洲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上殿如,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天贡珊,我揣著相機與錄音,去河邊找鬼涉馁。 笑死门岔,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的烤送。 我是一名探鬼主播寒随,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼帮坚!你這毒婦竟也來了牢裳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤叶沛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后忘朝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體灰署,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了溉箕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晦墙。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖肴茄,靈堂內(nèi)的尸體忽然破棺而出晌畅,到底是詐尸還是另有隱情,我是刑警寧澤寡痰,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布抗楔,位于F島的核電站,受9級特大地震影響拦坠,放射性物質(zhì)發(fā)生泄漏连躏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一贞滨、第九天 我趴在偏房一處隱蔽的房頂上張望入热。 院中可真熱鬧,春花似錦晓铆、人聲如沸勺良。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尚困。三九已至,卻和暖如春腰池,著一層夾襖步出監(jiān)牢的瞬間尾组,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工示弓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留讳侨,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓奏属,卻偏偏與公主長得像跨跨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子囱皿,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,185評論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理勇婴,服務(wù)發(fā)現(xiàn),斷路器嘱腥,智...
    卡卡羅2017閱讀 134,672評論 18 139
  • “七年之癢”的意思是說耕渴,許多事情發(fā)展到第七年就會不以人的意志出現(xiàn)一些問題,愛情當然也不例外齿兔。時間久了橱脸,新鮮感喪失础米。...
    星座的這一些事閱讀 200評論 0 0
  • 01.奴隸的你 大多數(shù)人屁桑,都樂于淪為身邊輿論場的奴隸。 在工作與生活的洪流中栏赴,不由自主地蘑斧,被沖擊,被同化须眷,最終竖瘾,被...
    微橙子閱讀 439評論 6 6
  • 我希望有這么一個人 給我波瀾不驚的愛情 承我此生美景 許你一世歡顏 十年前你是誰 一年前你是誰 甚至昨天你是誰 都...
    傾心一文閱讀 316評論 0 0