简体   繁体   中英

UWP MVVM Observablecollection has updated but not reflected on UI

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 :

  1. 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

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

        }

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM