2011-04-17 52 views
1

我遇到了一個WPF小問題,並將我的列表框/列表視圖綁定到自定義列表。列表框不顯示我的第一個項目

此列表包含IEnumerator & IEnumerable接口實現。如果我將控制權綁定到那些人,我永遠不會看到該列表的第一個對象。

當我gridview,它確實顯示我的第一個對象。所以出於某種原因,listbox/listview做了不同的事情來枚舉我的自定義列表。

我的綁定是用於設置完全相同的方式,使用我的ViewModel上的公共屬性。

綁定(我的PersonObject有一個公共屬性ProjectList,它獲取我正在討論的自定義列表)。

public Person Person 
    { 
     get 
     { 
      return this._person; 
     } 
     set 
     { 
      if (this._person != value) 
      { 
       this._person = value; 
       RaisePropertyChanged("Person"); 
      } 
     } 
    } 

的XAML:

<ListBox ItemsSource="{Binding Path=Person.ProjectList,UpdateSourceTrigger=PropertyChanged}" AlternationCount="2" ItemContainerStyle="{StaticResource CustomListBoxItemStyle}"> 
       <ListBox.ItemTemplate> 
        <DataTemplate> 
         <StackPanel> 
          <TextBlock> 
          <TextBlock.Text> 
           <MultiBinding StringFormat="{}{0} - {1}"> 
            <Binding Path="Name" /> 
            <Binding Path="Number" /> 
           </MultiBinding> 
          </TextBlock.Text> 
          </TextBlock> 
          <TextBlock> 
          <TextBlock.Text> 
           <MultiBinding StringFormat="{}{0} - {1}"> 
            <Binding Path="StartDate" /> 
            <Binding Path="EndDate" /> 
           </MultiBinding> 
          </TextBlock.Text> 
          </TextBlock> 
         </StackPanel> 
        </DataTemplate> 
       </ListBox.ItemTemplate> 
      </ListBox> 

的Customlist類:

public class ProjectList : DeletableSupport, IEnumerator, IEnumerable 
{ 
    private IList<Project> _pList; 

    private int _position; 

    public ProjectList() 
    { 
     this._pList = new ActivatableList<Project>(); 
     this._position = -1; 
    } 

    public void Add(Project p) 
    { 
     Activate(ActivationPurpose.Write); 
     this._pList.Add(p); 
    } 

    public void Remove(Project p) 
    { 
     Activate(ActivationPurpose.Write); 
     this._pList.Remove(p); 
    } 

    public int Count() 
    { 
     Activate(ActivationPurpose.Read); 
     return this._pList.Count(); 
    } 

    public bool Contains(Project p) 
    { 
     Activate(ActivationPurpose.Read); 
     return this._pList.Contains(p); 
    } 

    public Project this[int i] 
    { 
     get 
     { 
      Activate(ActivationPurpose.Read); 
      return this._pList[i]; 
     } 
     set 
     { 
      Activate(ActivationPurpose.Write); 
      this._pList[i] = value; 
     } 
    } 

    public static ProjectList operator +(ProjectList pList, Project p) 
    { 
     pList.Add(p); 
     return pList; 
    } 

    public static ProjectList operator -(ProjectList pList, Project p) 
    { 
     pList.Remove(p); 
     return pList; 
    } 

    #region IEnumerable Members 

    public IEnumerator GetEnumerator() 
    { 
     Activate(ActivationPurpose.Read); 
     return (IEnumerator)this; 
    } 

    #endregion 

    #region IEnumerator Members 

    public object Current 
    { 
     get 
     { 
      try 
      { 
       Activate(ActivationPurpose.Read); 
       return this._pList[_position]; 
      } 
      catch (IndexOutOfRangeException) 
      { 
       throw new InvalidOperationException(); 
      } 
     } 
    } 

    public bool MoveNext() 
    { 
     Activate(ActivationPurpose.Read); 
     this._position++; 
     if (_position < this._pList.Count) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 

    public void Reset() 
    { 
     Activate(ActivationPurpose.Write); 
     _position = -1; 
    } 

    #endregion 
} 

的激活是從db4o中,該ActivatableList實現IList

+1

張貼代碼應該有幫助。 – jfs 2011-04-17 15:58:57

回答

3

我要大膽的猜測在這裏,只是爲了測試我的心靈調試技巧:)

ListBox/ListView正在使用IEnumerable.Any()(或一些等價物)來測試列表是否爲空。這是真的,所以它然後使用您的IEnumerable實現來實際遍歷列表。

請注意,它沒有在您的類上調用reset,這意味着Any()調用檢索到的第一個元素將被跳過。

通常在IEnumerable上調用GetEnumerator將爲您的類返回一個新的IEnumerator實例,但實際的列表實現包含枚舉器的所有狀態。你是否考慮過如果你第二次將這個列表傳遞給你的ListBox會發生什麼?我不認爲你會看到任何東西。

好的,那該怎麼解決?那麼,考慮到你有的代碼,只要有人調用GetEnumerator(),就可以調用Reset()。 但是你的實現不是線程安全的(現在可能不是問題,但是誰知道將來如何使用它?)。如果你真的不想使用像ObservableCollection這樣的東西來存儲你的項目列表,我至少會看看從GetEnumerator方法中返回一個單獨的IEnumerator實例,枚舉過程的所有狀態都保存在那裏。

+0

事實上,對於我的其他答覆,重置不會在某個時間點被調用,在這裏做一些調試以讓事情再次發生......您的心理調試技巧並沒有失敗耶:) – 2011-04-17 16:56:15

相關問題