欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

WPF MVVM模式DataGrid

程序员文章站 2022-07-13 22:25:16
...

1.构造MVVM基本功能类

因为没有使用MVVM框架,所以要自己构造两个MVVM的基本功能类,完成属性通知和命令绑定 

1.1 属性通知

    /// <summary>
    /// INotifyPropertyChanged 用于通知属性改变(实现ViewModel向View喊话,所有绑定该属性的都会得到通知)
    /// </summary>
    public class NotificationObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 属性改变时调用该方法发出通知
        /// </summary>
        /// <param name="propertyName"></param>
        public void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

1.2 命令

public class DelegateCommand<T> : ICommand
    {
        private readonly Action<T> _executeMethod = null;
        private readonly Func<T, bool> _canExecuteMethod = null;

        public DelegateCommand(Action<T> executeMethod)
            : this(executeMethod, null)
        { }

        public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
        {
            if (executeMethod == null)
                throw new ArgumentNullException("executeMetnod");
            _executeMethod = executeMethod;
            _canExecuteMethod = canExecuteMethod;
        }

        #region ICommand 成员
        /// <summary>
        ///  Method to determine if the command can be executed
        /// </summary>
        public bool CanExecute(T parameter)
        {
            if (_canExecuteMethod != null)
            {
                return _canExecuteMethod(parameter);
            }
            return true;

        }

        /// <summary>
        ///  Execution of the command
        /// </summary>
        public void Execute(T parameter)
        {
            if (_executeMethod != null)
            {
                _executeMethod(parameter);
            }
        }

        #endregion


        event EventHandler ICommand.CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        #region ICommand 成员

        public bool CanExecute(object parameter)
        {
            if (parameter == null && typeof(T).IsValueType)
            {
                return (_canExecuteMethod == null);

            }

            return CanExecute((T)parameter);
        }

        public void Execute(object parameter)
        {
            Execute((T)parameter);
        }

        #endregion
    }

2.构造Model,ViewModel

    public class Person
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
public class PersonModel : NotificationObject
    {
        private bool _IsSelected = false;

        /// <summary>
        /// 是否选中
        /// </summary>
        public bool IsSelected
        {
            get
            {
                return _IsSelected;
            }
            set
            {
                _IsSelected = value;
                this.RaisePropertyChanged();
            }
        }

        private Person _Person;
        public Person Person
        {
            get
            {
                return _Person;
            }
            set
            {
                _Person = value;
                this.RaisePropertyChanged();
            }
        }
    }
    public class PersonListViewModel : NotificationObject
    {
        public PersonListViewModel()
        {
            _Persons.Add(new PersonModel() { Person = new Person() { ID = 1, Name = "张三" } });
            _Persons.Add(new PersonModel() { Person = new Person() { ID = 2, Name = "李四" } });
            _Persons.Add(new PersonModel() { Person = new Person() { ID = 3, Name = "王五" } });
            _Persons.Add(new PersonModel() { Person = new Person() { ID = 4, Name = "赵六" } });
            _Persons.Add(new PersonModel() { Person = new Person() { ID = 5, Name = "刘七" } });
            _Persons.Add(new PersonModel() { Person = new Person() { ID = 6, Name = "陈八" } });
        }

        private ObservableCollection<PersonModel> _Persons = new ObservableCollection<PersonModel>();
        public ObservableCollection<PersonModel> Persons
        {
            get
            {
                return _Persons;
            }
            set
            {
                _Persons = value;
                this.RaisePropertyChanged();
            }
        }


        private bool _IsSelectAll = false;
        public bool IsSelectAll
        {
            get { return _IsSelectAll; }
            set
            {
                _IsSelectAll = value;
                RaisePropertyChanged();
            }
        }


        private ICommand _SelectAllCommand;
        public ICommand SelectAllCommand
        {
            get
            {
                return _SelectAllCommand ?? (_SelectAllCommand = new DelegateCommand<object>(SelectAll));
            }
        }

        /// <summary>
        /// 全选
        /// </summary>
        /// <param name="id"></param>
        public void SelectAll(object id)
        {
            foreach (var item in Persons)
            {
                item.IsSelected = IsSelectAll;
            }
        }

        private ICommand _SelectCommand;
        public ICommand SelectCommand
        {
            get
            {
                return _SelectCommand ?? (_SelectCommand = new DelegateCommand<int>(Select));
            }
        }

        /// <summary>
        /// 单选
        /// </summary>
        /// <param name="id"></param>
        public void Select(int id)
        {
            PersonModel md = Persons.Where(p => p.Person.ID == id).FirstOrDefault();
            if (md != null)
            {
                if (!md.IsSelected && IsSelectAll)
                {
                    IsSelectAll = false;
                }
                else if (md.IsSelected && !IsSelectAll)
                {
                    foreach (var item in Persons)
                    {
                        if (!item.IsSelected) return;
                    }
                    IsSelectAll = true;
                }
            }
        }

        /// <summary>
        /// 判断是否选中
        /// </summary>
        /// <param name="onlyOne">是否单选</param>
        /// <returns></returns>
        public bool SelectValidate(bool onlyOne = false)
        {
            if (this.Persons.Count(p => p.IsSelected) < 1)
            {
                MessageBox.Show("未勾选数据!");
                return false;
            }

            if (onlyOne)
            {
                if (this.Persons.Count(p => p.IsSelected) > 1)
                {
                    MessageBox.Show("只能勾选一条数据!");
                    return false;
                }
            }

            return true;
        }

        private ICommand _DelCommand;
        public ICommand DelCommand
        {
            get
            {
                return _DelCommand ?? (_DelCommand = new DelegateCommand<object>(Del));
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="obj"></param>
        public void Del(object obj = null)
        {
            if (!SelectValidate()) return;

            MessageBoxResult result = MessageBox.Show("是否删除选中项?", "提示", MessageBoxButton.YesNo);
            if (result != MessageBoxResult.Yes)
            {
                return;
            }

            StringBuilder sb = new StringBuilder();

            bool hasSelect = false;
            //获取选中的数据
            foreach (var v in _Persons)
            {
                if (v.IsSelected) { sb.Append(v.Person.Name + ";"); hasSelect = true; }
            }
            if (!hasSelect)
            {
                MessageBox.Show("请选择修改项", "警告");
                return;
            }

            MessageBox.Show("选中 " + sb.ToString());
        }

        private ICommand _EditCommand;
        public ICommand EditCommand
        {
            get
            {
                return _EditCommand ?? (_EditCommand = new DelegateCommand<object>(Edit));
            }
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="obj"></param>
        public void Edit(object obj = null)
        {
            if (!SelectValidate(true)) return;

            PersonModel model = null;


            bool hasSelect = false;
            //获取选中的数据
            foreach (var v in _Persons)
            {
                if (v.IsSelected) { model = v; hasSelect = true; break; }
            }
            if (!hasSelect)
            {
                MessageBox.Show("请选择修改项", "警告");
                return;
            }

            MessageBox.Show("选中 " + model.Person.Name);

        }
    }
<!--uc_PersonList.xaml-->
<!--需要将Checkbox的点击事件绑定到Command命令,引用System.Windows.Interactivity程序集可实现Event to Command功能,方式:引用 => 程序集 => 扩展 => System.Windows.Interactivity -->
<UserControl x:Class="MvvmDataGridCheckBoxSelectAll.uc_PersonList"
             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" 
             xmlns:local="clr-namespace:MvvmDataGridCheckBoxSelectAll"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             mc:Ignorable="d">
    <UserControl.DataContext>
        <local:PersonListViewModel />
    </UserControl.DataContext>

    <DockPanel Margin="0">
        <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
            <Button Command="{Binding EditCommand}" ToolTip="修改">
                <Button.Content>
                    <StackPanel Orientation="Horizontal" >
                        <Image Stretch="None" VerticalAlignment="Center" Source="../Images/List_Edit.png"/>
                        <TextBlock Text="修改" VerticalAlignment="Center"/>
                    </StackPanel>
                </Button.Content>
            </Button>
            <Button Command="{Binding DelCommand}" ToolTip="删除">
                <Button.Content>
                    <StackPanel Orientation="Horizontal" >
                        <Image Stretch="None" VerticalAlignment="Center" Source="../Images/List_Del.png"/>
                        <TextBlock Text="删除" VerticalAlignment="Center"/>
                    </StackPanel>
                </Button.Content>
            </Button>
            <!--<Button Command="{Binding RefreshCommand}" ToolTip="刷新">
                <Button.Content>
                    <StackPanel Orientation="Horizontal" >
                        <Image Stretch="None" VerticalAlignment="Center" Source="../Images/List_Refresh.png"/>
                        <TextBlock Text="刷新" VerticalAlignment="Center"/>
                    </StackPanel>
                </Button.Content>
            </Button>-->

        </StackPanel>

        <DataGrid x:Name="dataGrid" AutoGenerateColumns="False" GridLinesVisibility="None" CanUserAddRows="False" Focusable="False"   Margin="0" HorizontalAlignment="Left" VerticalAlignment="Top" ItemsSource="{Binding Persons}" Width="Auto" EnableColumnVirtualization="False">

            <DataGrid.ColumnHeaderStyle>
                <Style TargetType="DataGridColumnHeader">
                    <Setter Property="HorizontalContentAlignment" Value="Center">
                    </Setter>
                </Style>
            </DataGrid.ColumnHeaderStyle>
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.Header>
                        <CheckBox IsChecked="{Binding DataContext.IsSelectAll,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource AncestorType=UserControl, AncestorLevel=1 }}">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="Click">
                                    <i:InvokeCommandAction Command="{Binding DataContext.SelectAllCommand ,RelativeSource={RelativeSource AncestorType=UserControl, AncestorLevel=1 }}" ></i:InvokeCommandAction>
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </CheckBox>
                    </DataGridTemplateColumn.Header>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox Margin="3" IsChecked="{Binding IsSelected,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                                <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="Click">
                                        <i:InvokeCommandAction Command="{Binding DataContext.SelectCommand ,RelativeSource={RelativeSource AncestorType=UserControl, AncestorLevel=1 }}" CommandParameter="{Binding Person.ID}" ></i:InvokeCommandAction>
                                    </i:EventTrigger>
                                </i:Interaction.Triggers>
                            </CheckBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTextColumn Binding="{Binding Person.Name}" Header="姓名" IsReadOnly="True" Width="*"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </DockPanel>
</UserControl>

 

相关标签: WPF MVVM