YoMo
YoMo

Reputation: 43

Listbox and observablecollection in wpf

I have listBox that show invoice items :

        <ListBox x:Name="lbInvoice" ItemsSource="{Binding ocItemsinInvoice}"  Margin="10,27,0,143" Width="412" HorizontalAlignment="Left" BorderBrush="{x:Null}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <ToggleButton x:Name="btnInvoiceItem" Checked="btnInvoiceItem_Checked" Style="{StaticResource InvoiceBG}" TabIndex="{Binding ItemsinInvoiceID}" Padding="20,0,0,0" FontSize="12" Width="408" Height="35" Foreground="#FFcfcfcf" IsChecked="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}, Mode=FindAncestor}}" BorderThickness="1,0.5">
                        <ToggleButton.BorderBrush>
                            <SolidColorBrush Color="#FF5B616F" Opacity="0.7"/>
                        </ToggleButton.BorderBrush>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding Item.ItemName}" Width="200"/>
                            <TextBlock Text="{Binding SalePrice}" Width="50"/>
                            <TextBlock Text="{Binding Quantity,NotifyOnSourceUpdated=True}" Width="50"/>
                            <TextBlock Text="{Binding Total}" Width="50"/>
                        </StackPanel>
                    </ToggleButton>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

The problem is when I change the quantity value in code behind (click event for example)

ItemsinInvoice _lbi = (ItemsinInvoice)lbInvoice.SelectedItem;
_lbi.Quantity = 99; //for example

on screen the value of quantity in the list dose not change, did I miss any thing.

Thanks

Upvotes: 0

Views: 329

Answers (1)

dkozl
dkozl

Reputation: 33364

If you want your changes to ViewModel to be automatically reflected in the view then your class needs to implement INotifyPropertyChanged and you need to raise PropertyChanged event each time property has changed value:

public class ItemsinInvoice : INotifyPropertyChanged
{
    #region INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion

    private int _quantity;

    public int Quantity
    {
        get { return _quantity; }
        set
        {
            if (_quantity != value)
            {
                _quantity = value;
                OnPropertyChanged("Quantity");
            }
        }
    }
}

UPDATE

I do not know how to use this code, can you explane it?

It's very simple code but will try to break it down for you. First you need to implement INotifyPropertyChanged interface

public class ItemsinInvoice : INotifyPropertyChanged

This interface has one PropertyChanged event that you need to publish in your class

public event PropertyChangedEventHandler PropertyChanged;

then you you write helper method to safely raise this event for specified property name:

private void OnPropertyChanged(string propertyName)
{
   ...
}

and that's INotifyPropertyChanged implemented. Now you need to call above OnPropertyChanged(...) method with property name each time property changed value so in this example for public int Quantity { ... } your call looks like this OnPropertyChanged("Quantity") and you have to remember that it is case sensitive so property name must match exactly.
By implementing INotifyPropertyChanged interface and raising PropertyChanged event for property name you tell binding that property with this name changed its value and all related bindings require refresh.

Upvotes: 1

Related Questions