在WPF应用程序中利用IEditableObject接口实现可撤销编辑的对象

Model:Employee

using System.ComponentModel;

namespace WpfApplicationBindingSample.Models
{
    /// <summary>
    /// 业务实体(Business Entity)
    /// </summary>
    class Employee : INotifyPropertyChanged,IEditableObject
    {
        private string _firstName;

        public string FirstName
        {
            get { return _firstName; }
            set
            {
                if (_firstName != value)
                {
                    _firstName = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("FirstName"));
                        PropertyChanged(this, new PropertyChangedEventArgs("FullName"));
                    }
                }
            }
        }

        private string _lastName;
        public string LastName
        {
            get { return _lastName; }
            set
            {
                if (_lastName != value)
                {
                    _lastName = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("LastName"));
                        PropertyChanged(this, new PropertyChangedEventArgs("FullName"));
                    }
                }
            }
        }

        public string FullName
        {
            get
            {
                return FirstName + "," + LastName;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private Employee backup;//用这个字段来保存一个备份数据
        public void BeginEdit()
        {
            //开始编辑,此时将当前的状态保存起来,以便后续可以根据情况提交或者撤销更改
            backup = this.MemberwiseClone() as Employee;//通过克隆的方式直接地复制一份数据
        }

        public void CancelEdit()
        {
            //撤销编辑,此时将对象状态恢复到备份的状态
            this.FirstName = backup.FirstName;
            this.LastName = backup.LastName;
        }

        public void EndEdit()
        {
            //结束编辑,这里可以不做任何事情,也可以添加一些额外的逻辑
        }
    }
}

ViewModel:

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Windows;
using WpfApplicationBindingSample.Models;

namespace WpfApplicationBindingSample.ViewModels
{
    /// <summary>
    /// 视图模型:专门用来为界面(视图)来服务的,这里用来包含一些业务逻辑
    /// </summary>
    class MainWindowViewModel : ViewModelBase
    {

        public MainWindowViewModel()
        {
            CurrentEmployee = new Employee()
            {
                FirstName = "ares",
                LastName = "chen"
            };
        }

        public Employee CurrentEmployee { get; set; }
        public RelayCommand EditCommand {
            get {
                return new RelayCommand(() => {
                    //将该员工设置为开始编辑
                    CurrentEmployee.BeginEdit();
                });
            }
        }

        /// <summary>
        /// 使用命令的机制代替了事件
        /// </summary>
        public RelayCommand SubmitCommand
        {
            get
            {//使用匿名方法
                return new RelayCommand(() =>
                {
                    //结束编辑,让更改生效
                    CurrentEmployee.EndEdit();

                    MessageBox.Show(CurrentEmployee.FullName);
                });
            }
        }

        public RelayCommand CancelCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    CurrentEmployee.CancelEdit();//取消编辑,此时可以看到FullName那个标签的文本恢复到原来的值
                });
            }
        }
    }
}

View:

<Window x:Class="WpfApplicationBindingSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:WpfApplicationBindingSample.ViewModels"
        Title="MainWindow"
        Height="350"
        Width="525">

    <Window.DataContext>
        <!--绑定数据上下文-->
        <vm:MainWindowViewModel></vm:MainWindowViewModel>
    </Window.DataContext>

    <Window.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Margin"
                    Value="3"></Setter>
        </Style>

        <Style TargetType="TextBox">
            <Setter Property="Width"
                    Value="200"></Setter>
            <Setter Property="HorizontalAlignment"
                    Value="Left"></Setter>
        </Style>

        <Style TargetType="Button">
            <Setter Property="Width"
                    Value="100"></Setter>
            <Setter Property="HorizontalAlignment"
                    Value="Left"></Setter>
        </Style>

    </Window.Resources>

    <StackPanel Margin="10">
        <TextBlock FontSize="30"
                   Text="编辑员工"></TextBlock>

        <TextBlock Text="姓氏"></TextBlock>
        <TextBox Text="{Binding CurrentEmployee.FirstName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>
        <!--匈牙利命名法-->
        <TextBlock Text="名称"></TextBlock>
        <TextBox Text="{Binding CurrentEmployee.LastName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>

        <TextBlock Text="全称"></TextBlock>
        <TextBlock Text="{Binding CurrentEmployee.FullName}"></TextBlock>

        <Button Content="编辑"
                Command="{Binding EditCommand}"></Button>
            <Button Content="提交"
                Command="{Binding SubmitCommand}"></Button>
        <Button Content="取消"
                Command="{Binding CancelCommand}"></Button>

    </StackPanel>

</Window>
posted @ 2018-07-16 14:50  dxm809  阅读(168)  评论(0编辑  收藏  举报