1
votes

I have ObservableCollection and WPF ListBox to bind each other. I want to display Chip position at Listbox simultaneously when ObservableCollection is added.

<Window x:Class="Apeiron.ZoneSetter.ZoneSetterWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
        Height="765" Width="765">
         <Grid>                  
            <ListBox Name="lbPosList" ItemsSource="{Binding }" ></ListBox>
         </Grid>
 </Window>

Case 1) It works well. When ObservableCollection is changed, it shows chnaged chip pos at ListBox.

public partial class ZoneSetterWindow : Window, INotifyPropertyChanged
  {
    public ZoneSetterWindow()
    {
        InitializeComponent();
        lbChipList.DataContext = SelectedZoneChipList;            
    }

    public void AddChip(ZoneMapChipInfo chip)
    {
          if (!m_SelectedChipDic.ContainsKey(chip.Point))
        {
            m_SelectedChipDic.Add(chip.ChipPos, chip);                
            m_selectedzonechiplist.Add(chip);
        }
    }


    private Dictionary<Point, ZoneMapChipInfo> m_SelectedChipDic = new Dictionary<Point, ZoneMapChipInfo>();

    private ObservableCollection<ZoneMapChipInfo> m_selectedzonechiplist = new ObservableCollection<ZoneMapChipInfo>();
    public ObservableCollection<ZoneMapChipInfo> SelectedZoneChipList
    {
        get
        {
            return m_selectedzonechiplist;
        }

    }       

  }

Case 2) It doesn't work. Although ObservableCollection is changed, it doesn't shows chnaged chip pos at ListBox.

public partial class ZoneSetterWindow : Window, INotifyPropertyChanged
{
    public ZoneSetterWindow()
    {
        InitializeComponent();
        lbChipList.DataContext = SelectedZoneChipList;            
    }

    public void AddChip(ZoneMapChipInfo chip)
    {
          if (!m_SelectedChipDic.ContainsKey(chip.Point))
        {
            m_SelectedChipDic.Add(chip.ChipPos, chip);                
            m_selectedzonechiplist.Add(chip);
        }
    }


    private Dictionary<Point, ZoneMapChipInfo> m_SelectedChipDic = new Dictionary<Point, ZoneMapChipInfo>();

    private ObservableCollection<ZoneMapChipInfo> m_selectedzonechiplist = new ObservableCollection<ZoneMapChipInfo>();
    public ObservableCollection<ZoneMapChipInfo> SelectedZoneChipList
    {
        get
        {
             ObservableCollection<WaferZoneMapChipInfo> result = new ObservableCollection<WaferZoneMapChipInfo>();
            foreach (ZoneMapChipInfo info in m_SelectedChipDic.Values)
            {
                result.Add(info);
            }
            return result;
        }

    }       

}

I want to synchronize m_SelectedChipDic and SelectedZoneChipList always, and show ChipPosition of SelectedZoneChipList at ListBox.

I don't know differernce of above two case.

Is there someone to understand me about above problem. Thank You!!

1

1 Answers

1
votes

Your problem is that in your first approach SelectedZoneChipList returns m_selectedzonechiplist to which the list view is then bound. This is why it is updating the UI when you add something to that list. In your second approach SelectedZoneChipList returns a completely new list unrelated to m_selectedzonechiplist. So when you add something to m_selectedzonechiplist nothing will happen because the ListBox is bound to a completely different object.

The binding to the ListBox works roughly like this:

  1. The UI gets the DataContext once when it establishes the binding.
  2. It subscribes to the CollectionChanged changed event handler (which ObservableCollection implements).
  3. Every time the collection is changed it raises an event to which the UI reacts.

Update: In regards to I want to synchronize m_SelectedChipDic and SelectedZoneChipList always: You could get rid of the ObservableCollection and make your m_SelectedChipDic an ObservableDictionary and bind your ListView to that one instead.