ObservableCollection и WPF ListBox Binding - PullRequest
       32

ObservableCollection и WPF ListBox Binding

1 голос
/ 19 ноября 2011

У меня есть ObservableCollection и WPF ListBox для привязки друг к другу. Я хочу отображать положение чипа в списке одновременно при добавлении ObservableCollection.

<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>

Случай 1) Хорошо работает. Когда ObservableCollection изменяется, он отображает chnaged chip pos в 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;
        }

    }       

  }

Случай 2) Это не работает. Несмотря на то, что ObservableCollection изменен, в ListBox он не отображает chnaged chip pos.

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;
        }

    }       

}

Я хочу синхронизировать m_SelectedChipDic и SelectedZoneChipList всегда, и показать ChipPosition SelectedZoneChipList в ListBox.

Я не знаю различий вышеупомянутых двух случаев.

Есть ли кто-нибудь, чтобы понять меня по поводу вышеупомянутой проблемы. Благодарю вас!!

1 Ответ

1 голос
/ 19 ноября 2011

Ваша проблема в том, что при первом подходе SelectedZoneChipList возвращает m_selectedzonechiplist, к которому затем привязывается представление списка.Вот почему он обновляет интерфейс, когда вы добавляете что-то в этот список.В вашем втором подходе SelectedZoneChipList возвращает совершенно новый список, не связанный с m_selectedzonechiplist.Поэтому, когда вы добавляете что-то к m_selectedzonechiplist, ничего не произойдет, потому что ListBox связан с совершенно другим объектом.

Привязка к ListBox работает примерно так:

  1. Пользовательский интерфейс получает DataContext один раз, когда устанавливает привязку.
  2. Он подписывается на измененный обработчик событий CollectionChanged (который реализует ObservableCollection).
  3. Каждый раз, когда коллекцияизменено, вызывает событие, на которое реагирует пользовательский интерфейс.

Обновление : в отношении I want to synchronize m_SelectedChipDic and SelectedZoneChipList always: вы можете избавиться от ObservableCollection и сделать свой m_SelectedChipDic an ObservableDictionary и вместо этого привяжите ListView к этому.

...