none
MVVM Light DataGrid Update RRS feed

  • Question

  • I wrote a small application in MVVM Light and the Entity Framework to display a list inside a DataGrid.

    Context:

    public partial class City
        {
            public int ID { get; set; }
            public string CityName { get; set; }
        }
        public partial class Customer
        {
            public int ID { get; set; }
            public string Name { get; set; }
            public int? ResidenceID { get; set; }
    
            [ForeignKey("ResidenceID")]
            public virtual City ResidenceT { get; set; }
        }
        public class MyContext : DbContext
        {
            public MyContext()
                : base("name=MyContext")
            {
                Database.SetInitializer<MyContext>(new CreateDatabaseIfNotExists<MyContext>());
            }
            public DbSet<City> Cities { get; set; }
            public DbSet<Customer> Customers { get; set; }
        }

    XAML:

    <Window x:Class="MvvmLight_DataGridAddRow.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:ignore="http://www.ignore.com"
            mc:Ignorable="d ignore"
            Height="300"
            Width="300"
            Title="MVVM Light Application"
            DataContext="{Binding Main, Source={StaticResource Locator}}">
    
        <Window.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="Skins/MainSkin.xaml" />
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Window.Resources>
    
        <Grid x:Name="LayoutRoot">
    
            <Button Content="Select" Command="{Binding SearchCommand}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75"/>
            <Button Content="Add" Command="{Binding AddCommand}" HorizontalAlignment="Left" Margin="10,45,0,0" VerticalAlignment="Top" Width="75"/>
            <TextBox Text="{Binding SelectedCity, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Height="23" Margin="90,42,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
            <DataGrid ItemsSource="{Binding ListCustomer, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False" SelectionUnit="FullRow" SelectionMode="Single" IsReadOnly="True" HorizontalAlignment="Left" Margin="10,80,0,0" VerticalAlignment="Top" Height="179" Width="272">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ID" Binding="{Binding ID}" />
                    <DataGridTextColumn Header="FirstName" Binding="{Binding Name}" />
                    <DataGridTextColumn Header="City" Binding="{Binding ResidenceT.CityName}" />
                </DataGrid.Columns>
            </DataGrid>
    
        </Grid>
    </Window>
    

    MainViewModel:

    public class MainViewModel : ViewModelBase
        {
            Customer entityCustomer;
            City entityCity;
    
            private int _Id;
            public int ID
            {
                get
                {
                    return _Id;
                }
    
                set
                {
                    Set(() => ID, ref _Id, value);
                }
            }
    
            private string _Name = string.Empty;
            public string Name
            {
                get
                {
                    return _Name;
                }
    
                set
                {
                    Set(() => Name, ref _Name, value);
                }
            }
    
            private List<Customer> _ListCustomer;
            public List<Customer> ListCustomer
            {
                get
                {
                    return _ListCustomer;
                }
                set
                {
                    Set(() => ListCustomer, ref _ListCustomer, value);
                }
            }
    
            private string _SelectedCity = string.Empty;
            public string SelectedCity
            {
                get
                {
                    return _SelectedCity;
                }
    
                set
                {
                    Set(() => SelectedCity, ref _SelectedCity, value);
                }
            }
            public RelayCommand SearchCommand { get; private set; }
            public RelayCommand AddCommand { get; private set; }
    
            public MainViewModel()
            {
                SearchCommand = new RelayCommand(() => Search());
                AddCommand = new RelayCommand(() => Add());
            }
            private void Search()
            {
                using (var ctx = new MyContext())
                {
                    ctx.Configuration.LazyLoadingEnabled = false;
                    ctx.Configuration.ProxyCreationEnabled = false;
    
                    ListCustomer = ctx.Customers
                        .Include("ResidenceT")
                        .Where(s => s.Name.Equals("Robert"))
                        .ToList();
                }
            }
            private void Add()
            {
                using (var ctx = new MyContext())
                {
                    entityCity = ctx.Cities.SingleOrDefault(x => x.CityName.StartsWith(SelectedCity));
    
                    entityCustomer = new Customer { Name = "Robert", ResidenceT = entityCity };
    
                    ListCustomer.Add(entityCustomer);
                }
            }

    Within the application contains a textbox where you can add the cities.

    However my problem is that I can't update the DataGrid with the newly added cities.


    Sunday, May 10, 2015 5:06 PM

Answers

  • >>However my problem is that I can't update the DataGrid with the newly added cities.

    Replace the List<Customer> with an ObservableCollection<Customer> in your view model class:

        public class MainViewModel : ViewModelBase
        {
            Customer entityCustomer;
            City entityCity;
    
            private int _Id;
            public int ID
            {
                get
                {
                    return _Id;
                }
    
                set
                {
                    Set(() => ID, ref _Id, value);
                }
            }
    
            private string _Name = string.Empty;
            public string Name
            {
                get
                {
                    return _Name;
                }
    
                set
                {
                    Set(() => Name, ref _Name, value);
                }
            }
    
            private System.Collections.ObjectModel.ObservableCollection<Customer> _ListCustomer;
            public System.Collections.ObjectModel.ObservableCollection<Customer> ListCustomer
            {
                get
                {
                    return _ListCustomer;
                }
                set
                {
                    Set(() => ListCustomer, ref _ListCustomer, value);
                }
            }
    
            private string _SelectedCity = string.Empty;
            public string SelectedCity
            {
                get
                {
                    return _SelectedCity;
                }
    
                set
                {
                    Set(() => SelectedCity, ref _SelectedCity, value);
                }
            }
            public RelayCommand SearchCommand { get; private set; }
            public RelayCommand AddCommand { get; private set; }
    
            public MainViewModel()
            {
                SearchCommand = new RelayCommand(() => Search());
                AddCommand = new RelayCommand(() => Add());
            }
            private void Search()
            {
                using (var ctx = new MyContext())
                {
                    ctx.Configuration.LazyLoadingEnabled = false;
                    ctx.Configuration.ProxyCreationEnabled = false;
    
                    var customers = ctx.Customers
                        .Include("ResidenceT")
                        .Where(s => s.Name.Equals("Robert"))
                        .ToList();
    
                    ListCustomer = new System.Collections.ObjectModel.ObservableCollection<Customer>(customers);
            }
            private void Add()
            {
                using (var ctx = new MyContext())
                {
                    entityCity = ctx.Cities.SingleOrDefault(x => x.CityName.StartsWith(SelectedCity));
    
                    entityCustomer = new Customer { Name = "Robert", ResidenceT = entityCity };
    
                    ListCustomer.Add(entityCustomer);
                }
            }
    }
    

    An ObservableCollection provides notifications when items get added or removed: https://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx

    A List does not.

    Please remember to close your threads by marking helpful posts as answer and then start a new thread if you have a new question. Please don't ask several questions in the same thread.

    Sunday, May 10, 2015 6:58 PM

All replies

  • >>However my problem is that I can't update the DataGrid with the newly added cities.

    Replace the List<Customer> with an ObservableCollection<Customer> in your view model class:

        public class MainViewModel : ViewModelBase
        {
            Customer entityCustomer;
            City entityCity;
    
            private int _Id;
            public int ID
            {
                get
                {
                    return _Id;
                }
    
                set
                {
                    Set(() => ID, ref _Id, value);
                }
            }
    
            private string _Name = string.Empty;
            public string Name
            {
                get
                {
                    return _Name;
                }
    
                set
                {
                    Set(() => Name, ref _Name, value);
                }
            }
    
            private System.Collections.ObjectModel.ObservableCollection<Customer> _ListCustomer;
            public System.Collections.ObjectModel.ObservableCollection<Customer> ListCustomer
            {
                get
                {
                    return _ListCustomer;
                }
                set
                {
                    Set(() => ListCustomer, ref _ListCustomer, value);
                }
            }
    
            private string _SelectedCity = string.Empty;
            public string SelectedCity
            {
                get
                {
                    return _SelectedCity;
                }
    
                set
                {
                    Set(() => SelectedCity, ref _SelectedCity, value);
                }
            }
            public RelayCommand SearchCommand { get; private set; }
            public RelayCommand AddCommand { get; private set; }
    
            public MainViewModel()
            {
                SearchCommand = new RelayCommand(() => Search());
                AddCommand = new RelayCommand(() => Add());
            }
            private void Search()
            {
                using (var ctx = new MyContext())
                {
                    ctx.Configuration.LazyLoadingEnabled = false;
                    ctx.Configuration.ProxyCreationEnabled = false;
    
                    var customers = ctx.Customers
                        .Include("ResidenceT")
                        .Where(s => s.Name.Equals("Robert"))
                        .ToList();
    
                    ListCustomer = new System.Collections.ObjectModel.ObservableCollection<Customer>(customers);
            }
            private void Add()
            {
                using (var ctx = new MyContext())
                {
                    entityCity = ctx.Cities.SingleOrDefault(x => x.CityName.StartsWith(SelectedCity));
    
                    entityCustomer = new Customer { Name = "Robert", ResidenceT = entityCity };
    
                    ListCustomer.Add(entityCustomer);
                }
            }
    }
    

    An ObservableCollection provides notifications when items get added or removed: https://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx

    A List does not.

    Please remember to close your threads by marking helpful posts as answer and then start a new thread if you have a new question. Please don't ask several questions in the same thread.

    Sunday, May 10, 2015 6:58 PM
  • First of all thanks for the quick reply.I realized that my difficulty in finding a viable solution was due to my habit to use List<>.

    Now I understand that: ObservableCollection is a generic dynamic data collection that provides notifications - update UI -, using an interface "INotifyCollectionChanged", when items get added, removed, or when the whole collection is refreshed.

    Monday, May 11, 2015 9:19 AM