Search code examples
wpflistviewmvvmdata-bindingitemsource

How to update a listview from viewmodel binded model observable collection to itemsource


I have a list view, which further contains textbox in datatemplate having columns Name, Address, Country. Now this listview's Itemsource is binded to observable collection of a model in my viewmodel class.

I am updating the ObjModel (of typeObservableCollection<Model>) by making name and address empty, on some condition in VM, and i can see the values of name, empty in my ObjModel object in viewmodel class. But those changes are not reflected in UI (ListView), Am i missing something , How to update the listview.

My View is something like this:

 <DataTemplate x:Key="EquipmentItemTemplate">
                <Grid
                    x:Name="ListItem"
                    Height="40"
                    ZIndex="1">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="200" />
                        <ColumnDefinition Width="250" />
                        <ColumnDefinition Width="250" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0" Text="{Binding Path=Name}" />
                    <TextBlock Grid.Column="1" Text="{Binding Path=Address}" />
                    <TextBlock Grid.Column="2" Text="{Binding Path=Country}" />
                </Grid>
            </DataTemplate>
 <ListView x:Name="MaintenanceElements" 
                 ItemContainerStyle="{StaticResource SequenceListItemStyle}"
                 ItemTemplate="{StaticResource EquipmentItemTemplate}"
                ItemsSource="{Binding EquipmentMaintenanceEntityItemsCollection}"
                SelectedItem="{Binding SelectedMaintenanceElement}">
                    <ListView.View>
                        <GridView AllowsColumnReorder="False">
                            <GridViewColumn
                                    Width="200"
                                    local:GridViewSort.PropertyName="Name"
                                    Header="Name" />
                            <GridViewColumn
                                    Width="250"
                                    local:GridViewSort.PropertyName="Address"
                                    Header="Address" />
                            <GridViewColumn
                                    Width="250"
                                    local:GridViewSort.PropertyName="Country"
                                    Header="Country" />

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

View Model contains:

 public ObservableCollection<Model> ObjModel { get; set; }

Some where on some condition i do

ObjModel[0].Name= string.Empty; 

It do not update in ListView because its itemsource is binded to Model object observable collection, how to update ListView from here?

My model is:

public class EquipmentMaintenanceModel : ChangeTracker, INotifyPropertyChanged
    {
      private string name;
      private string address;
      private string country;

       public string Name
        {
            get { return this.name; }
            set { this.name = value; }
        }

       public string Address
        {
            get { return this.address; }
            set { this.address = value; }
        }
       public string Country
        {
            get { return this.country; }
            set { this.country = value; }
        }
        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

Solution

  • In your model, you need to fire PropertyChanged when you set the value of a property. eg:

    public string Name
      {
        get { return this.name; }
        set 
        {
          if(this.name != value)
          {
            this.name = value;
            OnPropertyChanged(Name);
          }
        }
      }