Reputation: 45
I am begginer to UWP and MVVM I try to bind my observablecollection to gridview control which successfully bind on page load and when bind command to button and from that button i am adding new item to my observablecollection then it is not reflected on UI don't know that is issue here but while debugging i can see that my collection has been updated please help
what i have tried is :
- my view is
<Grid>
<Button Content="Update" Grid.Row="12" Height="35" Grid.Column="0" Margin="90,15,0,0" Name="btnUpdate"
VerticalAlignment="Top" Width="141"
Command="{Binding Path=UpdateCommand}" />
<controls:DataGrid x:Name="dgvEmpList" Margin="0,0,480,457"
Grid.Row="1" Grid.RowSpan="12" Grid.Column="1" GridLinesVisibility="All"
AlternatingRowBackground="LightBlue"
HeadersVisibility="Column"
ItemsSource="{Binding Users, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedUser, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
AutoGenerateColumns="False"
>
<controls:DataGrid.Columns>
<controls:DataGridTextColumn
Header="UserId"
Binding="{Binding UserId}"
/>
<controls:DataGridTextColumn
Header="FirstName"
Binding="{Binding FirstName}"
/>
<controls:DataGridTextColumn
Header="LastName"
Binding="{Binding LastName}"
/>
<controls:DataGridTextColumn
Header="City"
Binding="{Binding City}" />
<controls:DataGridTextColumn
Header="State"
Binding="{Binding State}" />
<controls:DataGridTextColumn
Header="Country"
Binding="{Binding Country}" />
</controls:DataGrid.Columns>
</controls:DataGrid>
</Grid>
and my model is
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
}
and my viewmodel is
public class UserViewModel : INotifyPropertyChanged, ICommand
{
private ObservableCollection<User> _UsersList { get; set; }
private User selecteduser;
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChangedEventArgs args = new PropertyChangedEventArgs(propertyName);
this.PropertyChanged(this, args);
}
}
public UserViewModel()
{
_UsersList = new ObservableCollection<User>
{
new User{UserId = 1,FirstName="Raj",LastName="Beniwal",City="Delhi",State="DEL",Country="INDIA"},
new User{UserId=2,FirstName="Mark",LastName="henry",City="New York", State="NY", Country="USA"},
new User{UserId=3,FirstName="Mahesh",LastName="Chand",City="Philadelphia", State="PHL", Country="USA"},
new User{UserId=4,FirstName="Vikash",LastName="Nanda",City="Noida", State="UP", Country="CANADA"},
new User{UserId=5,FirstName="Harsh",LastName="Kumar",City="Ghaziabad", State="UP", Country="INDIA"},
new User{UserId=6,FirstName="Reetesh",LastName="Tomar",City="Mumbai", State="MP", Country="INDIA"},
new User{UserId=7,FirstName="Deven",LastName="Verma",City="Palwal", State="HP", Country="ENGLAND"},
new User{UserId=8,FirstName="Ravi",LastName="Taneja",City="Delhi", State="DEL", Country="INDIA"}
};
}
public User SelectedUser
{
get
{
return selecteduser;
}
set
{
selecteduser = value;
NotifyPropertyChanged("SelectedUser");
}
}
public ObservableCollection<User> Users
{
get
{ return _UsersList; }
set
{
_UsersList = value;
NotifyPropertyChanged("Users");
}
}
private ICommand mUpdater;
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_UsersList.Add(
new User
{
FirstName = "ABC",
LastName = "XYZ",
City = "TEST",
Country = "TESTREST",
State = "GUJRAT",
UserId = 9
});
}
public ICommand UpdateCommand
{
get
{
if (mUpdater == null)
mUpdater = new UserViewModel();
return mUpdater;
}
set
{
mUpdater = value;
}
}
}
in viewmodel when button clicks it goes to canexecute() then execute() and onexecute() my Observablecollection has updated from 8 items to 9 items but it not shows in UI
One more question is if i want pass dynamic values to that ObservableCollection to Add new item then how can i do that
Upvotes: 1
Views: 232
Reputation: 5868
The error occurs on ICommand, the ICommand you are using is not recommended. It's better to create a command class inherited from ICommand. First, you can follow this document to create a RelayCommand and then create UpdateCommand property that type is RelayCommand.
public class UserViewModel : INotifyPropertyChanged
{
private ObservableCollection<User> _UsersList { get; set; }
private User selecteduser;
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChangedEventArgs args = new PropertyChangedEventArgs(propertyName);
this.PropertyChanged(this, args);
}
}
public UserViewModel()
{
......
UpdateCommand = new RelayCommand(UpdateCustomer);
}
......
public RelayCommand UpdateCommand { get; set; }
public void UpdateCustomer()
{
Users.Add(
new User
{
FirstName = "ABC",
LastName = "XYZ",
City = "TEST",
Country = "TESTREST",
State = "GUJRAT",
UserId = 9
});
}
}
Update:
Just take TextBox as a simple example, you can use CommandParameter to bind the Text of TextBox.
.xaml:
<TextBox x:Name="MyTextBox" Width="300"></TextBox>
<Button ...... Command="{Binding Path=UpdateCommand}" CommandParameter="{Binding ElementName=MyTextBox,Path=Text}"/>
Since the parameters are passed in, the writing of RelayCommand also needs to be changed accordingly.
public class RelayCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Func<bool> _canExecute;
public event EventHandler CanExecuteChanged;
public RelayCommand(Action<object> updateCustomer)
{
_execute = updateCustomer;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute();
}
public void Execute(object parameter)
{
_execute(parameter);
}
public void RaiseCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
public class UserViewModel : INotifyPropertyChanged
{
......
public void UpdateCustomer(object parameter)
{
//add Users
}
}
Upvotes: 3