如何使用列表在wpf mvvm上插入更新删除操作?

时间:2014-08-10 12:41:48

标签: wpf mvvm

这里我已经编写了更新操作,我也想知道如何在MVVM上执行插入和删除操作?

View section:

filename:Person.xaml ---->它是UI设计文件

<Window x:Class="WpfApplication5.View.Person"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Person" Height="300" Width="300" 
        xmlns:y="clr-namespace:WpfApplication5.ViewModel">
    <Grid>

        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"></RowDefinition>
                <RowDefinition Height="auto"></RowDefinition>
            </Grid.RowDefinitions>
            <Label x:Name="lblName" Content="Name" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top"></Label>
            <TextBox x:Name="txtName" Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" Text="{Binding ElementName=lstPerson, Path=SelectedItem.Name}"></TextBox>
            <Label x:Name="lblAddress" Content="Address" Grid.Row="1" Grid.Column="0" VerticalAlignment="Top"></Label>
            <TextBox x:Name="txtAddress" Grid.Row="1" Grid.Column="1" VerticalAlignment="Top" Text="{Binding ElementName=lstPerson, Path=SelectedItem.Address}"></TextBox>
        </Grid>
        <Button x:Name="btnUpdate" Width="100" Height="20" HorizontalAlignment="Center" Grid.Row="1" Content="Update"
                Command="{Binding Path=UpdateCommand}" CommandParameter="{Binding ElementName=lstPerson, Path=SelectedItem.Address}"></Button>
        <ListView x:Name="lstPerson" Grid.Row="2" ItemsSource="{Binding Persons}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
                    <GridViewColumn Header="Address" Width="200" DisplayMemberBinding="{Binding Address}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>


VieModel section:

文件名是:PersonViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using WpfApplication5.Model;

namespace WpfApplication5.ViewModel
{
    class PersonViewModel
    {
        private IList<Person> _personList;
        public PersonViewModel()
        {
            _personList = new List<Person>()
            {
                new Person(){Name="Prabhat", Address="Bangalore"},
                new Person(){Name="John",Address="Delhi"}
            };
        }
        public IList<Person> Persons
        {
            get { return _personList; }
            set { _personList = value; }
        }
        private ICommand mUpdater;
        public ICommand UpdateCommand
        {
            get
            {
                if (mUpdater == null)
                    mUpdater = new Updater();
                return mUpdater;
            }
            set
            {
                mUpdater = value;
            }
        }
    }
    class Updater : ICommand
    {
        #region ICommand Members

        public bool CanExecute(object parameter)
        {
            return true;
        }

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

        public void Execute(object parameter)
        {
            //Your Code
        }

        #endregion
    }
}

Model section:

filename是:Person.cs

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

namespace WpfApplication5.Model
{
    class Person : INotifyPropertyChanged
    {
        private string name;
        private string address;

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }
        public string Address
        {
            get
            {
                return address;
            }
            set
            {
                address = value;
                OnPropertyChanged("Address");
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

不使用 List<T> ,而是使用ObservableCollection进行源代码收集。

原因是它实现了 INotifyCollectionChanged ,这意味着对此列表的任何插入/添加/删除操作都将自动刷新有界UI。您无需担心提升收集更改事件。

private ObservableCollection<Person> _personList;
public ObservableCollection<Person> Persons
{
   get { return _personList; }
   set { _personList = value; }
}

此外,不要为每个ICommand实现创建单独的类,而应考虑使用 RelayCommand DelegateCommand 的通用版本。

<强> RelayCommand

public class RelayCommand<T> : ICommand
{
    #region Fields

    readonly Action<T> _execute = null;
    readonly Predicate<T> _canExecute = null;

    #endregion

    #region Constructors

    /// <summary>
    /// Initializes a new instance of <see cref="DelegateCommand{T}"/>.
    /// </summary>
    /// <param name="execute">Delegate to execute when Execute is called on the command.  This can be null to just hook up a CanExecute delegate.</param>
    /// <remarks><seealso cref="CanExecute"/> will always return true.</remarks>
    public RelayCommand(Action<T> execute)
        : this(execute, null)
    {
    }

    /// <summary>
    /// Creates a new command.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    /// <param name="canExecute">The execution status logic.</param>
    public RelayCommand(Action<T> execute, Predicate<T> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }

    #endregion

    #region ICommand Members

    ///<summary>
    ///Defines the method that determines whether the command can execute in its current state.
    ///</summary>
    ///<param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
    ///<returns>
    ///true if this command can be executed; otherwise, false.
    ///</returns>
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute((T)parameter);
    }

    ///<summary>
    ///Occurs when changes occur that affect whether or not the command should execute.
    ///</summary>
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    ///<summary>
    ///Defines the method to be called when the command is invoked.
    ///</summary>
    ///<param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to <see langword="null" />.</param>
    public void Execute(object parameter)
    {
        _execute((T)parameter);
    }

    #endregion
}

使用RelayCommand并在ViewModel类中创建处理程序,如下所示:

private ICommand mUpdater;
public ICommand UpdateCommand
{
    get
    {
       if (mUpdater == null)
          mUpdater = new RelayCommand<object>(Update);
       return mUpdater;
    }
}

private void Update(object parameter)
{
    // Update collection based on the parameter passed from View.
}