1. 程式人生 > >使用WPF+MVVM模式的小案例

使用WPF+MVVM模式的小案例

WPF+MVVM模式的小案例案例主要的目錄結構

下面一步一步建立整個小程式的目錄和相應的程式碼程式。

1、開啟VS, 新建專案WPFDemo.Client.CustType(自己可以寫自己的程式名稱,這個自定義取決於自己)

2、在建資料夾Data,Models,OthersServices,ViewModels,Views等資料夾。

3、資料夾Data中新增CustTypeData.xml檔案。內容如下:

<?xml version="1.0" encoding="utf-8" ?>
<Cust_TypeS>
  <Cust_Type>
    <CUSTTYPE_ID>104</CUSTTYPE_ID>
    <CUSTTYPE_NO></CUSTTYPE_NO>
    <CUSTTYPE_NAME>華北</CUSTTYPE_NAME>
    <REM>子區域的上級區域不顯子區域的上級區域不顯子區域的上級區域不顯子區域的上級區域不顯子;域的上級··不!</REM>
  </Cust_Type>
  <Cust_Type>
    <CUSTTYPE_ID>105</CUSTTYPE_ID>
    <CUSTTYPE_NO></CUSTTYPE_NO>
    <CUSTTYPE_NAME>華南</CUSTTYPE_NAME>
    <REM>ssdfdsdfsd</REM>
  </Cust_Type>
  <Cust_Type>
    <CUSTTYPE_ID>106</CUSTTYPE_ID>
    <CUSTTYPE_NO></CUSTTYPE_NO>
    <CUSTTYPE_NAME>華西</CUSTTYPE_NAME>
    <REM>域的上級··不!</REM>
  </Cust_Type>
  <Cust_Type>
    <CUSTTYPE_ID>111</CUSTTYPE_ID>
    <CUSTTYPE_NO></CUSTTYPE_NO>
    <CUSTTYPE_NAME>華東</CUSTTYPE_NAME>
    <REM>子區區域</REM>
  </Cust_Type>
  <Cust_Type>
    <CUSTTYPE_ID>113</CUSTTYPE_ID>
    <CUSTTYPE_NO></CUSTTYPE_NO>
    <CUSTTYPE_NAME>444</CUSTTYPE_NAME>
    <REM>444</REM>
  </Cust_Type>
</Cust_TypeS>

4、資料夾Models中新增Cust_Type.cs檔案。內容如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Windows.Controls;

namespace WPFDemo.Client.CustType.Models
{
    /// <summary>
    /// 客戶分類
    /// </summary>
    public partial class Cust_Type
    {
        private long _CUSTTYPE_ID;
        /// <summary>
        /// ID
        /// </summary>
        public long CUSTTYPE_ID
        {
            get { return _CUSTTYPE_ID; }
            set { _CUSTTYPE_ID = value; }
        }

        private string _CUSTTYPE_NO;
        /// <summary>
        /// 分類編碼
        /// </summary>
        public string CUSTTYPE_NO
        {
            get { return _CUSTTYPE_NO; }
            set { _CUSTTYPE_NO = value; }
        }

        private string _CUSTTYPE_NAME;
        /// <summary>
        /// 名稱
        /// </summary>
        public string CUSTTYPE_NAME
        {
            get { return _CUSTTYPE_NAME; }
            set { _CUSTTYPE_NAME = value; }
        }

        private string _REM;
        /// <summary>
        /// 備註
        /// </summary>
        public string REM
        {
            get { return _REM; }
            set { _REM = value; }
        }


    }
}

5、資料夾Others新增OperatorEnum.cs檔案。內容如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WPFDemo.Client.CustType.Others
{
    /// <summary>
    /// 列舉運算元
    /// 增 Create = 1, 刪 Delete=2, 改 Update=3, 查 Retrieve=4
    /// </summary>
    public enum OperatorEnum
    {
        /// <summary>
        /// 增
        /// </summary>
        Create = 1,
        /// <summary>
        /// 刪
        /// </summary>
        Delete = 2,
        /// <summary>
        /// 改
        /// </summary>
        Update = 3,
        /// <summary>
        /// 查
        /// </summary>
        Retrieve = 4
    }
}

6、在Services中新增 IDataService.cs(資料讀取操作介面),IDataOperatorService.cs(資料儲存操作介面)檔案以及相應的實現檔案(可以根據相應的資料庫來實現相應的介面,如:sql server,oracle資料庫,xml檔案等),內容如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WPFDemo.Client.CustType.Models;

namespace WPFDemo.Client.CustType.Services
{
    /// <summary>
    /// 獲取資料介面
    /// </summary>
    public interface IDataService
    {
        /// <summary>
        /// 獲取資料列表
        /// </summary>
        /// <returns></returns>
        List<Cust_Type> GetCustTypeList();       
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WPFDemo.Client.CustType.Others;

namespace WPFDemo.Client.CustType.Services
{
    interface IDataOperatorService
    {
        void SaveCustTypeList(List<Models.Cust_Type> custTypeList, OperatorEnum enumData);
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using WPFDemo.Client.CustType.Models;

namespace WPFDemo.Client.CustType.Services
{
    /// <summary>
    /// 通過XML獲取資料
    /// </summary>
    class XmlDataService : IDataService
    {
        public List<Cust_Type> GetCustTypeList()
        {
            string localPath = Path.Combine(Environment.CurrentDirectory, @"Data\CustTypeData.xml");
            XDocument xdoc = XDocument.Load(localPath);
            var eleList = xdoc.Descendants(nameof(Cust_Type));
            List<Cust_Type> custTypeList = new List<Cust_Type>();
            foreach (var item in eleList)
            {
                Cust_Type temp = new Cust_Type();
                long id = 0;
                temp.CUSTTYPE_ID = long.TryParse(item.Element(nameof(Cust_Type.CUSTTYPE_ID)).Value, out id) ? id : 0;
                temp.CUSTTYPE_NO = item.Element(nameof(Cust_Type.CUSTTYPE_NO)).Value;
                temp.CUSTTYPE_NAME = item.Element(nameof(Cust_Type.CUSTTYPE_NAME)).Value;
                temp.REM = item.Element(nameof(Cust_Type.REM)).Value;
                custTypeList.Add(temp);
            }
            return custTypeList;
        }

    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using WPFDemo.Client.CustType.Models;
using WPFDemo.Client.CustType.Others;

namespace WPFDemo.Client.CustType.Services
{
    class XmlDataOperatorService : IDataOperatorService
    {
        public void SaveCustTypeList(List<Cust_Type> custTypeList)
        {
            //string localpath = System.IO.Path.Combine(Environment.CurrentDirectory, @"Data\xml.txt");
            //System.IO.File.AppendAllLines(localpath, custTypeList.Where(o => o.CUSTTYPE_ID != 0).Select(i => i.CUSTTYPE_NAME).ToArray());          
        }

        public void SaveCustTypeList(List<Cust_Type> custTypeList, OperatorEnum enumData)
        {
            //string localPath = Path.Combine(Environment.CurrentDirectory, @"Data\Data.xml");
            string localPath = @"Data\CustTypeData.xml";
            XDocument xdoc = XDocument.Load(localPath);
            switch (enumData)
            {
                case OperatorEnum.Create:
                    this.Create(xdoc, custTypeList);
                    break;
                case OperatorEnum.Delete:
                    this.Delete(xdoc, custTypeList);
                    break;
                case OperatorEnum.Update:
                    this.Update(xdoc, custTypeList);
                    break;
                    //case OperatorEnum.Retrieve:
                    //    this.Retrieve(xdoc, custTypeList);
                    //    break;
            }
        }

        public const string savePath = @"Data\CustTypeData.xml";

        /// <summary>
        /// 增
        /// </summary>
        public void Create(XDocument xdoc, List<Cust_Type> custTypeList, string path = savePath)
        {
            if (xdoc == null || custTypeList == null || custTypeList.Count <= 0)
                return;
            foreach (var item in custTypeList)
            {
                XElement element = new XElement(nameof(Cust_Type),
                    new XElement(nameof(Cust_Type.CUSTTYPE_ID), item.CUSTTYPE_ID),
                    new XElement(nameof(Cust_Type.CUSTTYPE_NO), item.CUSTTYPE_NO),
                    new XElement(nameof(Cust_Type.CUSTTYPE_NAME), item.CUSTTYPE_NAME),
                    new XElement(nameof(Cust_Type.REM), item.REM));
                if (xdoc.Root == null)
                {
                    xdoc.Add(new XElement("Cust_TypeS"));
                }
                xdoc.Root.Add(element);
            }
            xdoc.Save(path);
            System.Windows.MessageBox.Show("儲存成功!", "提示");
        }

        /// <summary>
        /// 刪
        /// </summary>
        public void Delete(XDocument xdoc, List<Cust_Type> custTypeList, string path = savePath)
        {
            if (xdoc == null || xdoc.Root == null || custTypeList == null || custTypeList.Count <= 0)
                return;

            var element = xdoc.Root.Descendants(nameof(Cust_Type));
            if (element == null)
            {
                return;
            }
            foreach (var item in custTypeList)
            {
                var delElement = element.FirstOrDefault(o => o.Element(nameof(Cust_Type.CUSTTYPE_ID)).Value.Equals(item.CUSTTYPE_ID.ToString()));
                if (delElement != null)
                {
                    delElement.Remove();
                }
            }
            xdoc.Save(path);
            System.Windows.MessageBox.Show("刪除成功!", "提示");
        }

        /// <summary>
        /// 改
        /// </summary>
        public void Update(XDocument xdoc, List<Cust_Type> custTypeList, string path = savePath)
        {
            if (xdoc == null || xdoc.Root == null || custTypeList == null || custTypeList.Count <= 0)
                return;
            var element = xdoc.Root.Descendants(nameof(Cust_Type));
            if (element == null)
            {
                return;
            }
            foreach (var item in custTypeList)
            {
                var delElement = element.FirstOrDefault(o => o.Element(nameof(Cust_Type.CUSTTYPE_ID)).Value.Equals(item.CUSTTYPE_ID.ToString()));
                if (delElement != null)
                {
                    //delElement.SetElementValue(nameof(Cust_Type.CUSTTYPE_ID), item.CUSTTYPE_ID);
                    delElement.SetElementValue(nameof(Cust_Type.CUSTTYPE_NO), item.CUSTTYPE_NO);
                    delElement.SetElementValue(nameof(Cust_Type.CUSTTYPE_NAME), item.CUSTTYPE_NAME);
                    delElement.SetElementValue(nameof(Cust_Type.REM), item.REM);
                }
            }
            xdoc.Save(path);
            System.Windows.MessageBox.Show("修改成功!", "提示");
        }

        /// <summary>
        /// 查
        /// </summary>
        public void Retrieve(XDocument xdoc, List<Cust_Type> custTypeList)
        {
            if (xdoc == null || custTypeList == null || custTypeList.Count <= 0)
                return;
            var element = xdoc.Root.Descendants(nameof(Cust_Type));
            if (element == null)
            {
                return;
            }
        }

        /// <summary>
        /// 查
        /// </summary>
        public bool IsExistElement(XDocument xdoc, Cust_Type custType)
        {
            if (xdoc == null || custType == null)
                return false;
            var element = xdoc.Root.Descendants(nameof(Cust_Type));
            if (element == null)
            {
                return false;
            }
            var delElement = element.FirstOrDefault(o => o.Element(nameof(Cust_Type.CUSTTYPE_ID)).Value.Equals(custType.CUSTTYPE_ID));
            if (delElement == null)
            {
                return false;
            }
            return true;
        }

    }
}

7、在ViewModels新增相應的ViewModel,內容如下:

using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WPFDemo.Client.CustType.Models;
using WPFDemo.Client.CustType.Services;
using WPFDemo.Client.Services;
using System.Collections.ObjectModel;
using System.Windows;
using WPFDemo.Client.CustType.Others;

namespace WPFDemo.Client.CustType.ViewModels
{
    /// <summary>
    /// 主介面檢視互動的ViewModel
    /// </summary>
    public class MainWindowViewModel : NotificationObject
    {
        #region 變數

        /// <summary>
        /// 增
        /// </summary>
        public DelegateCommand CreateCommand { get; set; }

        /// <summary>
        /// 刪
        /// </summary>
        public DelegateCommand DeleteCommand { get; set; }

        /// <summary>
        /// 改
        /// </summary>
        public DelegateCommand UpdateCommand { get; set; }

        /// <summary>
        /// 查
        /// </summary>
        public DelegateCommand RetrieveCommand { get; set; }

        private List<CustTypeOperatorViewModel> _CustTypeViewModel;

        public List<CustTypeOperatorViewModel> CustTypeViewModel
        {
            get { return _CustTypeViewModel; }
            set
            {
                _CustTypeViewModel = value;
                this.RaisePropertyChanged("CustTypeViewModel");
            }
        }


        private CustTypeOperatorViewModel custTypeOperatorViewModel;

        public CustTypeOperatorViewModel CustTypeOperatorViewModel
        {
            get { return custTypeOperatorViewModel; }
            set
            {
                custTypeOperatorViewModel = value;
                this.RaisePropertyChanged("CustTypeOperatorViewModel");
            }
        }

        private ObservableCollection<CustTypeOperatorViewModel> _ObsCCustTypeViewModel;
        public ObservableCollection<CustTypeOperatorViewModel> ObsCCustTypeViewModel
        {
            get { return _ObsCCustTypeViewModel; }
            set
            {
                _ObsCCustTypeViewModel = value;
                this.RaisePropertyChanged("ObsCCustTypeViewModel");
            }
        }


        #endregion

        public MainWindowViewModel()
        {
            this.LoadCustTypeViewModelData();
            LoadObsCCustTypeViewModelData();
            this.CreateCommand = new DelegateCommand(new Action(this.Create));
            this.DeleteCommand = new DelegateCommand(new Action(this.Delete));
            this.UpdateCommand = new DelegateCommand(new Action(this.Update));
            this.RetrieveCommand = new DelegateCommand(new Action(this.Retrieve));
        }

        #region 方法

        public void LoadCustTypeViewModelData()
        {
            Services.IDataService ds = new XmlDataService();
            var data = ds.GetCustTypeList();
            this.CustTypeViewModel = new List<CustTypeOperatorViewModel>();
            foreach (var item in data)
            {
                CustTypeOperatorViewModel custTypeViewModel = new CustTypeOperatorViewModel();
                custTypeViewModel.CustType = item;
                this.CustTypeViewModel.Add(custTypeViewModel);
            }
            //this.CustTypeOperatorViewModel = this.ObsCCustTypeViewModel.FirstOrDefault();
        }
        public void LoadObsCCustTypeViewModelData()
        {
            Services.IDataService ds = new XmlDataService();
            var data = ds.GetCustTypeList();
            this.ObsCCustTypeViewModel = new ObservableCollection<CustTypeOperatorViewModel>();
            foreach (var item in data)
            {
                CustTypeOperatorViewModel custTypeViewModel = new CustTypeOperatorViewModel();
                custTypeViewModel.CustType = item;
                this.ObsCCustTypeViewModel.Add(custTypeViewModel);
            }
            this.CustTypeOperatorViewModel = this.ObsCCustTypeViewModel.FirstOrDefault();
        }

        /// <summary>
        /// 增
        /// </summary>
        public void Create()
        {
            CustTypeOperatorViewModel obj = new CustTypeOperatorViewModel();
            obj.CustType = new Cust_Type();
            Random ran = new Random();
            obj.CustType.CUSTTYPE_ID = ran.Next(10000);
            this.ObsCCustTypeViewModel.Add(obj);
            SubWindow dlg = new SubWindow(obj, OperatorEnum.Create);
            dlg.ShowDialog();
            //List<Cust_Type> list = this.ObsCCustTypeViewModel.Where(o => o.isSelected == true).Select(i => i.CustType).ToList();
        }

        /// <summary>
        /// 刪
        /// </summary>
        public void Delete()
        {

            List<Cust_Type> list = this.ObsCCustTypeViewModel.Where(o => o.isSelected == true).Select(i => i.CustType).ToList();
            if (list != null)
            {
                if (list.Count > 0)
                {
                    if (MessageBox.Show("是否刪除?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                    {
                        IDataOperatorService idos = new XmlDataOperatorService();
                        idos.SaveCustTypeList(list, Others.OperatorEnum.Delete);
                        List<CustTypeOperatorViewModel> selectList = this.ObsCCustTypeViewModel.Where(o => o.isSelected == true).Select(i => i).ToList();
                        foreach (var item in selectList)
                        {
                            this.ObsCCustTypeViewModel.Remove(item);
                        }
                        return;
                    }
                }
                if (list.Count == 0)
                {
                    CustTypeOperatorViewModel obj = this.CustTypeOperatorViewModel;
                    if (obj == null)
                    {
                        return;
                    }
                    Cust_Type Cust_Type = new Cust_Type();
                    Cust_Type = obj.CustType;
                    list.Add(Cust_Type);
                    if (MessageBox.Show("是否刪除?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                    {
                        IDataOperatorService idos = new XmlDataOperatorService();
                        idos.SaveCustTypeList(list, Others.OperatorEnum.Delete);
                        this.ObsCCustTypeViewModel.Remove(obj);
                    }
                }
            }
            MessageBox.Show("沒有滿足可以刪除的條件的刪除刪除項!", "提示");
        }

        /// <summary>
        /// 改
        /// </summary>
        public void Update()
        {
            //CustTypeOperatorViewModel obj = this.ObsCCustTypeViewModel.FirstOrDefault();
            CustTypeOperatorViewModel obj = this.CustTypeOperatorViewModel;
            SubWindow dlg = new SubWindow(obj, OperatorEnum.Update);
            dlg.ShowDialog();
            //System.Windows.MessageBox.Show("修改成功!", "提示");
        }

        /// <summary>
        /// 查
        /// </summary>
        public void Retrieve()
        {
            System.Windows.MessageBox.Show("查詢成功!", "提示");
        }

        #endregion
    }
}

using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.ViewModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WPFDemo.Client.CustType.Others;
using WPFDemo.Client.CustType.Services;

namespace WPFDemo.Client.CustType.ViewModels
{
    public class SubWindowViewModel : NotificationObject
    {

        public DelegateCommand SaveCommand { get; set; }

        public DelegateCommand CancelCommand { get; set; }

        public OperatorEnum enumData { get; set; }

        private CustTypeOperatorViewModel _ObsCCustTypeViewModel;
        public CustTypeOperatorViewModel ObsCCustTypeViewModel
        {
            get { return _ObsCCustTypeViewModel; }
            set
            {
                _ObsCCustTypeViewModel = value;
                this.RaisePropertyChanged("ObsCCustTypeViewModel");
            }
        }

        public SubWindowViewModel()
        {
            this.SaveCommand = new DelegateCommand(new Action(SaveData));
            this.CancelCommand = new DelegateCommand(new Action(CancelData));

            Services.IDataService ds = new XmlDataService();
            var data = ds.GetCustTypeList();
            this.ObsCCustTypeViewModel = new CustTypeOperatorViewModel();
            ObsCCustTypeViewModel.CustType = data.FirstOrDefault();
           
        }
        public SubWindowViewModel(CustTypeOperatorViewModel CustTypeViewModel, OperatorEnum enumData = OperatorEnum.Update)
        {
            this.enumData = enumData;
            this.SaveCommand = new DelegateCommand(new Action(SaveData));
            this.CancelCommand = new DelegateCommand(new Action(CancelData));

            this.ObsCCustTypeViewModel = CustTypeViewModel;
        }
        public void SaveData()
        {
            CustTypeOperatorViewModel ss = this.ObsCCustTypeViewModel;
            IDataOperatorService save = new XmlDataOperatorService();
            save.SaveCustTypeList(new List<Models.Cust_Type> { ss.CustType }, this.enumData);
        }
        public void CancelData()
        {
            System.Windows.MessageBox.Show("取消!", "提示");
        }
    }
}

using Microsoft.Practices.Prism.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WPFDemo.Client.CustType.ViewModels
{
    public class CustTypeOperatorViewModel : NotificationObject
    {
        public Models.Cust_Type CustType { get; set; }


        //private Models.Cust_Type custType;

        //public Models.Cust_Type CustType
        //{
        //    get { return custType; }
        //    set
        //    {
        //        custType = value;
        //    }
        //}

        private bool isselected;

        public bool isSelected
        {
            get { return isselected; }
            set
            {
                isselected = value;
                this.RaisePropertyChanged("isSelected");
            }
        }


    }
}

8、最後設計MainWindow.xaml主介面的內容,如下:

<Window x:Class="WPFDemo.Client.CustType.MainWindow"
        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:local="clr-namespace:WPFDemo.Client.CustType"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" WindowStartupLocation="CenterScreen">
    <Border BorderBrush="Orange" CornerRadius="6" Padding="4">
        <Grid x:Name="root" Margin="4">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>
            <Border BorderThickness="1" Padding="4" CornerRadius="6">
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                    <ToolBar>
                        <Button Content="查詢" Command="{Binding RetrieveCommand}"></Button>
                        <Button Content="新增" Command="{Binding CreateCommand}"></Button>
                        <Button Content="編輯" Command="{Binding UpdateCommand}"></Button>
                        <Button Content="刪除" Command="{Binding DeleteCommand}"></Button>
                    </ToolBar>
                </StackPanel>
            </Border>
            <DataGrid x:Name="DataGrid" AutoGenerateColumns="False" Grid.Row="1" CanUserAddRows="False" FontSize="16"
                      CanUserDeleteRows="False" GridLinesVisibility="All" ItemsSource="{Binding ObsCCustTypeViewModel,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding CustTypeOperatorViewModel,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ID" Width="120" Binding="{Binding CustType.CUSTTYPE_ID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                    <DataGridTextColumn Header="分類編碼" Width="120" Binding="{Binding CustType.CUSTTYPE_NO,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                    <DataGridTextColumn Header="名稱" Width="120" Binding="{Binding CustType.CUSTTYPE_NAME,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                    <DataGridTextColumn Header="備註" Width="120" Binding="{Binding CustType.REM,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                    <DataGridTemplateColumn Header="選中" SortMemberPath="isSelected" Width="120">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding Path=isSelected,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
                                          VerticalAlignment="Center" HorizontalAlignment="Center" Command="{Binding see,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Grid.Row="2">
                <StatusBar>
                    <StatusBarItem Content="狀態"></StatusBarItem>
                </StatusBar>
            </StackPanel>
        </Grid>
    </Border>

</Window>


相應後臺新增

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WPFDemo.Client.CustType.ViewModels;

namespace WPFDemo.Client.CustType
{
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindowViewModel();
        }
    }
}
9、另一個彈窗介面,介面設計,內容如下:

<Window x:Class="WPFDemo.Client.CustType.SubWindow"
        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:local="clr-namespace:WPFDemo.Client.CustType"
        mc:Ignorable="d"
        Title="SubWindow" Height="320.858" Width="417.811" WindowStartupLocation="CenterScreen">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Border BorderThickness="1" Padding="4" CornerRadius="6" Grid.Row="0">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="詳情" FontSize="12" FontFamily="Lishu"/>
            </StackPanel>
        </Border>
        <Border BorderThickness="1" Padding="4" CornerRadius="6" Grid.Row="1">
            <StackPanel>
                <Border BorderThickness="1" Padding="4" CornerRadius="6">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="ID:" FontSize="16" FontFamily="Lishu"/>
                        <TextBox Width="265" Height="Auto" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
                         TextWrapping="WrapWithOverflow" FontSize="16" FontFamily="Lishu"
                         Text="{Binding ObsCCustTypeViewModel.CustType.CUSTTYPE_ID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                    </StackPanel>
                </Border>
                <Border BorderThickness="1" Padding="4" CornerRadius="6">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="分類編碼:" FontSize="16" FontFamily="Lishu"/>
                        <TextBox Width="217" Height="Auto" FontSize="16" FontFamily="Lishu"
                         Text="{Binding ObsCCustTypeViewModel.CustType.CUSTTYPE_NO,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                    </StackPanel>
                </Border>
                <Border BorderThickness="1" Padding="4" CornerRadius="6">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="名稱:" FontSize="16" FontFamily="Lishu"/>
                        <TextBox Width="250" Height="Auto" FontSize="16" FontFamily="Lishu"
                         Text="{Binding ObsCCustTypeViewModel.CustType.CUSTTYPE_NAME,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                    </StackPanel>
                </Border>
                <Border BorderThickness="1" Padding="4" CornerRadius="6">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="說明:" FontSize="16" FontFamily="Lishu"/>
                        <TextBox Width="249" Height="Auto" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
                         TextWrapping="WrapWithOverflow" FontSize="16" FontFamily="Lishu"
                         Text="{Binding ObsCCustTypeViewModel.CustType.REM,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                    </StackPanel>
                </Border>
            </StackPanel>
        </Border>
        <Border Padding="4" CornerRadius="6" Grid.Row="2">
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                <Border Padding="4">
                    <Button Content="儲存" Height="30" Width="60" Command="{Binding SaveCommand}"/>
                </Border>
                <Border Padding="4">
                    <Button Content="取消" Height="30" Width="60" Command="{Binding CancelCommand}"/>
                </Border>
            </StackPanel>
        </Border>
    </Grid>
</Window>

後臺相應程式碼內容,如下:

using Microsoft.Practices.Prism.Commands;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using WPFDemo.Client.CustType.Others;
using WPFDemo.Client.CustType.ViewModels;

namespace WPFDemo.Client.CustType
{
    /// <summary>
    /// SubWindow.xaml 的互動邏輯
    /// </summary>
    public partial class SubWindow : Window
    {
        public SubWindow(CustTypeOperatorViewModel CustTypeViewModel, OperatorEnum enumData= OperatorEnum.Update)
        {
            InitializeComponent();
            this.DataContext = new SubWindowViewModel(CustTypeViewModel, enumData);
        }
    }
}

到此為止,以上所有內容基本寫完,可以執行啦,介面如下: