这里我已经编写了更新操作,我也想知道如何在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");
}
}
}
}
答案 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.
}