Home > Software engineering >  WPF ViewModel Changes Not Updating Listview
WPF ViewModel Changes Not Updating Listview

Time:11-03

when a pressed to fetch data button , User_List in UserControllers is changed but listview in mainwindow is not updated.I use database as EntityFramework6.0 I share you UserController.cs(Viewmodel),Users.cs,MainWindow.cs,MainWindow.xaml How can I fix this?

MainWindows.cs

public partial class MainWindow : Window ,INotifyPropertyChanged

{
    ViewModels.UsersController controller1;

    public ObservableCollection<Users> user_List;

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    public ObservableCollection<Users> User_List
    {
        get { return user_List; }
        set {lst1.ItemsSource=user_List = value;OnPropertyChanged("User_List"); }
    }

    public MainWindow()
    {
        InitializeComponent();
        controller1 = new ViewModels.UsersController();
        this.DataContext = controller1;
    }
   
   
    private void Fetch_Data_Button_Click(object sender, RoutedEventArgs e)
    {
        ViewModels.UsersController controller = new ViewModels.UsersController();
        controller.Increase();
        lst1.UpdateLayout();
    }
}

MainWindow.xaml

Window x:Class="MSSQLServer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MSSQLServer"
        xmlns:vw="clr-namespace:MSSQLServer.ViewModels"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" >
    <Window.DataContext>
        <vw:UsersController/>
    </Window.DataContext>
    <Grid>
        <StackPanel Orientation="Vertical">
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                <Button x:Name="Fetch_Data_Button" Click="Fetch_Data_Button_Click" Content="Fetch Data" Width="150" Height="40" FontSize="18" Margin="10,10"></Button>
            </StackPanel>
            <ListView x:Name="lst1" HorizontalAlignment="Center" VerticalAlignment="Center" Height="300" Width="600" ItemsSource="{Binding User_List,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
                <ListView.View>
                    <GridView>
                        <GridView.Columns>
                            <GridViewColumn Header="Id" DisplayMemberBinding="{Binding id,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="50"></GridViewColumn>
                            <GridViewColumn Header="Name" DisplayMemberBinding="{Binding name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="120"></GridViewColumn>
                            <GridViewColumn Header="Surname" DisplayMemberBinding="{Binding surname,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="120"></GridViewColumn>
                            <GridViewColumn Header="Age" DisplayMemberBinding="{Binding age,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="120"></GridViewColumn>
                            <GridViewColumn Header="E-Mail" DisplayMemberBinding="{Binding email,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="120"></GridViewColumn>

                        </GridView.Columns>
                    </GridView>
                </ListView.View>
            </ListView>
           

        </StackPanel>
        
    </Grid>
</Window>

UserController.cs

public class UsersController :INotifyPropertyChanged
    {
        public ObservableCollection<Users> user_List;
        public ObservableCollection<Users> User_List
        {
            get { return user_List; }
            set { user_List = value;OnPropertyChanged("User_List"); }
        }
      
        public UsersController()
        {
            Increase();
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
       
       
        public void Increase()
        {
            Database1Entities entities = new Database1Entities();
            User_List = new ObservableCollection<Users>(entities.Users.ToList());
            
        }
    }

And Users.cs

public class Userss : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private int idd;
        public int id
        {
            get { return idd; }
            set { idd = value; OnPropertyChanged("id"); }
        }
        private string namee;
        public string name
        {
            get { return namee; }
            set { namee = value; OnPropertyChanged("name"); }
        }
        private string surnamee;
        public string surname
        {
            get { return surnamee; }
            set { surnamee = value; OnPropertyChanged("surname"); }
        }
        private int agee;
        public int age
        {
            get { return agee; }
            set { agee = value; OnPropertyChanged("age"); }
        }
        private string emaill;
        public string email
        {
            get { return emaill; }
            set { emaill = value; OnPropertyChanged("email"); }
        }

    }

CodePudding user response:

Take a look at my latest answer at: C# wpf listview binding problem with observable collection

It's a basic example of how to work listviews/treeviews/gridviews at least at the beginning. If you try it then you will move most of your code into ViewModel part, but then you will search for commands and interaction between them (prism might be ok - i mean event aggregation, don't go Dependency Injection too fast).

One of your classes is named UsersController. When you switch to WPF, remember that MVC pattern is no longer alive and most of it is somewhere in ViewModel, so it's more like UserViewModel or UsersViewModel. If I read you correctly then I'm telling you that it's hard to switch from classic MVC (various implementations) to some sort of correct, pleasant MVVM.

The URL I provided has one major thing missing which is the standard ViewModelWrapper, usually called ViewModelBase or BaseViewModel, call it yourself.

It takes shape of (it should be the part of my first post though):

namespace MyNamespace.ViewModel
{
    public class BaseViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler? PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName=null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = "")
        {
            if (EqualityComparer<T>.Default.Equals(storage, value))
                return false;
            storage = value;
            this.OnPropertyChanged(propertyName);
            return true;
        }

    }
}

CodePudding user response:

First of all, you should get rid of the following XAML since you are setting the DataContext programmatically:

<Window.DataContext>
    <vw:UsersController/>
</Window.DataContext>

Second, you should call the Increase() method of the data-bound instance of the UsersController:

private void Fetch_Data_Button_Click(object sender, RoutedEventArgs e)
{
    controller1.Increase();
}
  • Related