Как сохранить данные в 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}
Другие вопросы по тегам