Reputation: 288
I have my Model
class which implements INotifyPropertyChanged
.
My View has 5 TextBox
, 2 Button
and a ListView
to display grid.
In my ViewModel
I was previously adding default values to the ObservableCollection
of my Model
class and displaying it to a ListView
.
The button implementation is done using ICommand
and RelayCommand
.
Now I want to add data to the ObservableCollection
from the user from the UI TextBox
. How can I achieve that? The UI TextBox
hasbindings with properties of the Model
class.
My View
<ListView Name="UserGrid" Grid.Row="1" Margin="4,178,12,13" ItemsSource="{Binding UserDatas}" >
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,7,0,0" Name="txtUserId" VerticalAlignment="Top" Width="178" Text="{Binding UserId}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,35,0,0" Name="txtFirstName" VerticalAlignment="Top" Width="178" Text="{Binding FirstName}" />
Like these there are 5 TextBoxes
The Model
class:
public class User : INotifyPropertyChanged
{
private int userId;
private string firstName;
public int UserId
{
get
{
return userId;
}
set
{
userId = value;
RaisePropertyChanged("UserId");
}
}
}
The ViewModel:
public class UsersViewModel:INotifyPropertyChanged
{
private ObservableCollection<User> userDatas;
public ObservableCollection<User> UserDatas
{
get
{
if (userDatas == null)
{
userDatas = new ObservableCollection<User>();
}
return userDatas;
}
set
{
userDatas = value;
RaisePropertyChanged("UserDatas");
}
}
}
private CommandBase _LoadCommand;
public ICommand LoadCommand
{
get
{
if (this._LoadCommand == null)
this._LoadCommand = new CommandBase(LoadData);
return this._LoadCommand;
}
}
private void LoadData(object obj)
{
//What need to be done here to access the textboxes of UI which are binded to User.cs class.
User newUser = new User();
UserDatas.Add(newUser);
}
Now what I need to write in the LoadData method to take inputfrom textboxes from UI and store it in my ObservableCollection
Upvotes: 1
Views: 1724
Reputation: 64288
There are several things you can do. Most obvious, is to have a "Add New" Command, which creates a new empty object and stores it in a CurrentUser
or SelectedUser
property.
This property is bound to the Template's (or Form's) context. You'd have 3 commands (Add New User, Save User, Cancel to cancel addition of a new user creation).
For example
public class UsersViewModel : INotifyPropertyChanged
{
public UsersViewModel()
{
UserDatas = new ObservableCollection<User>();
AddNewUserCommand = new RelayCommand(AddNewUser, param => !this.IsNewUser);
SaveUserCommand = new RelayCommand(SaveUser);
CancelNewUserCommand = new RelayCommand(CancelNewUser, param => this.IsNewUser);
}
private ObservableCollection<User> userDatas;
public ObservableCollection<User> UserDatas
{
get { return userDatas; }
set
{
userDatas = value;
RaisePropertyChanged("UserDatas");
}
}
private User selectedUser;
public User SelectedUser
{
get { return selectedUser; }
set
{
selectedUser = value;
RaisePropertyChanged("SelectedUser");
RaisePropertyChanged("IsNewUser");
}
}
public bool IsNewUser
{
get
{
if(SelectedUser==null)
return false;
return SelectedUser.UserId == 0;
}
}
public ICommand AddNewUserCommand { get; private set; }
public ICommand CancelNewUserCommand { get; private set; }
public ICommand SaveUserCommand { get; private set; }
private void AddNewUser()
{
SelectedUser = new User();
}
private void SaveUser()
{
// Just in case of concurency
var newUser = SelectedUser;
if(newUser == null)
{
return;
}
var isNewUser = newUser.UserId == 0;
// Persist it to the database
this.userRepository.Add(newUser);
this.userRepository.SaveChanges();
// If all worked well, add it to the observable collection
if(isNewUser)
{
// Only add if new, otherwise it should be already in the collection
UserDatas.Add(newUser)
}
}
}
But again, it's very discouraged to work directly on the model and bind it to the View. You should also create a ViewModel for your User and put validation (implement the IDataErrorInfo
interface on the UserViewModel
) in there and handling of state, for example tracking if the UserViewModel
is dirty (i.e. data was changed).
All these are presentation concerns and not business logic, so they belong to a ViewModel and not to the Model itself.
Upvotes: 1