Как сохранить данные в ListBox по событию нажатия кнопки mvvm
Я должен ввести некоторые данные в текстовые поля и затем нажать кнопку "Сохранить". Данные, которые я написал, должны быть сохранены в списке ниже, который имеет тот же столбец, что и все текстовые поля. Я не в состоянии понять, как сохранить данные с помощью ICommand и передать их в ListBox, чтобы при сохранении их в тот же момент они отображались в Listbox.
Примерно так: http://prntscr.com/9nm6u8
Но я не могу понять, как связать данные таким образом, что, когда я помещаю текстовые поля, а затем нажимаю "Сохранить", необходимо обновить эту сетку этими данными, используя только MVVM.
Моя попытка сделать это (что очевидно, почему я здесь для помощи):
Мой полный код:
Модель:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfApplication1
{
public class User : INotifyPropertyChanged
{
private int userId;
private string firstName;
private string lastName;
private string city;
private string state;
private string country;
public int UserId
{
get
{
return userId;
}
set
{
userId = value;
OnPropertyChanged("UserId");
}
}
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = value;
OnPropertyChanged("FirstName");
}
}
public string LastName
{
get
{
return lastName;
}
set
{
lastName = value;
OnPropertyChanged("LastName");
}
}
public string City
{
get
{
return city;
}
set
{
city = value;
OnPropertyChanged("City");
}
}
public string State
{
get
{
return state;
}
set
{
state = value;
OnPropertyChanged("State");
}
}
public string Country
{
get
{
return country;
}
set
{
country = value;
OnPropertyChanged("Country");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
ViewModel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace WpfApplication1
{
class UserViewModel
{
private IList<User> _UsersList;
public UserViewModel()
{
_UsersList = new List<User>
{
// new User{UserId = 1,FirstName="sam",LastName="Disouza",City="lonero",State="Depra",Country="USA"},
};
}
/*
*
public UserViewModel(User usr)
{
_UsersList = new List<User>
{
new User{UserId = usr.UserId,FirstName=usr.FirstName,LastName=usr.LastName,City=usr.City,State=usr.State,Country=usr.Country},
};
}
*/
public IList<User> Users
{
get { return _UsersList; }
set { _UsersList = value; }
}
private ICommand mUpdater;
public ICommand SaveCommand
{
get
{
if (mUpdater == null)
mUpdater = new Updater();
return mUpdater;
}
set
{
mUpdater = value;
}
}
private class Updater : ICommand
{
#region ICommand Members
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
}
#endregion
}
}
}
Посмотреть:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView Name="UserGrid" Grid.Row="1" Margin="4,178,12,13" ItemsSource="{Binding Users}" >
<ListView.View>
<GridView x:Name="grdTest">
<GridViewColumn Header="UserId" DisplayMemberBinding="{Binding UserId}" Width="50"/>
<GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="80" />
<GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="100" />
<GridViewColumn Header="City" DisplayMemberBinding="{Binding City}" Width="80" />
<GridViewColumn Header="State" DisplayMemberBinding="{Binding State}" Width="80" />
<GridViewColumn Header="Country" DisplayMemberBinding="{Binding Country}" Width="100" />
</GridView>
</ListView.View>
</ListView>
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,7,0,0" Name="txtUserId" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid,Path=SelectedItem.UserId}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,35,0,0" Name="txtFirstName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid,Path=SelectedItem.FirstName}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,62,0,0" Name="txtLastName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid,Path=SelectedItem.LastName}" />
<Label Content="UserId" Grid.Row="1" HorizontalAlignment="Left" Margin="12,12,0,0" Name="label1" VerticalAlignment="Top" />
<Label Content="Last Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,60,0,0" Name="label2" VerticalAlignment="Top" />
<Label Content="First Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,35,0,0" Name="label3" VerticalAlignment="Top" />
<Button Content="Save" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="310,50,0,0" Name="btnSave"
VerticalAlignment="Top" Width="141"
Command="{Binding Path=SaveCommad}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,143,0,0" x:Name="txtCity" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.City, ElementName=UserGrid}" />
<Label Content="Country" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,141,0,0" x:Name="label2_Copy" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,88,0,0" x:Name="txtCountry" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.Country, ElementName=UserGrid}" />
<Label Content="City" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,86,0,0" x:Name="label2_Copy1" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,115,0,0" x:Name="txtSTate" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.State, ElementName=UserGrid}" />
<Label Content="State" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,113,0,0" x:Name="label2_Copy2" VerticalAlignment="Top" />
</Grid>
</Window>
View.cs
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;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new UserViewModel();
}
}
}
Может ли кто-нибудь помочь мне в достижении моей цели?
1 ответ
Я бы предложил использовать RelayCommand
связать вашу команду. Кроме того, вам нужно добавить параметр команды, если вы хотите отправить данные в вашу команду.
Посмотрите этот фрагмент кода http://snipplr.com/view/13642/ импортируйте класс и реализация ниже
2) В вашей команде есть опечатка SaveCommad
должно быть SaveCommand
Добавьте CommandParameter{Binding}, это отправит вашу модель представления в качестве контекста в вашей кнопке просмотра:
<Button Content="Save" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="310,50,0,0" Name="btnSave"
VerticalAlignment="Top" Width="141"
Command="{Binding Path=SaveCommad}",CommandParameter{Binding} />
ViewModel:
RelayCommand _saveCommand;
public ICommand SaveCommand
{
get
{
if (_saveCommand== null)
{
_saveCommand= new RelayCommand(p => this.SaveCommand((object)p),
p => this.CanSaveCommand(p) ); // you can set it to true for testing purpose or bind it to a property IsValid if u want to disable the button
}
return _saveCommand;
}
}
private void SaveCommand(object vm)
{
//Actual implementation to insert into list.
}
private bool CanSaveCommand(object vm)
{
return true;
}
YourViewModel : INotifyPropertyChange // to enable notification to your view
private User _currentUser;
public User CurrentUser {get return _currentUser;} set{_currentUser = value; NotifyPropertyChange("CurrentUser")
//Or Simply Insert all property of user to your viewmodel so your input have acces to content
private string _name;
public string Name {get return _name;} set{_name = value; NotifyPropertyChange("Name")
В вашем XAML для варианта 1:
Text={Binding CurrentUser.Name,Mode="TwoWay",UpdateSourceTrigger=PropertyChanged}
В вашем XAML для варианта 2:
Text={Binding Name,Mode="TwoWay",UpdateSourceTrigger=PropertyChanged}