2012-12-12 57 views
1

使用標準列表框我想將其綁定到一組對象並更新綁定項目集合以包含所選內容。Winforms綁定列表框中的SelectedItems

所以我有這樣的:

_pContext = new BindingSource(); 
_pContext.DataSource = _gpContext; 
_pContext.DataMember = "ParentEntities"; 
_AllChildrenListBox.DataSource = _container.ChildEntities; 
_AllChildrenListBox.DataBindings.Add("MySelectedItems", _pContext, "ChildEntities", false); 

_allChildrenListBox是列表框。我創建了一個從ListBox繼承的新列表框類型,所以我可以創建一個替代的SelectedItems屬性,然後封裝邏輯來設置/取消設置項目。

所以這個問題簡而言之就是:在上面,ChildEntities是一個「ChildEntity」對象的集合。我的列表框包含所有可能的ChildEntity對象,我希望選擇ChildEntities中的元素,並在選擇更改時進行更新。

回答

0

我找到了解決辦法。目前有點難看,但有效。我稍後可以改進它。

所以第一位是綁定本身。

_AllChildrenListBox.DataBindings.Add("SelectedItems2", _pContext, "ChildEntities2", true); 

這裏的關鍵似乎是將格式參數設置爲true。

接下來我需要一些在SelectedItems2中做我的骯髒工作。這是一團糟,但工作。下面是完整的類:

public class MyListBox : ListBox 
{ 
    private IEnumerable<object> _original; 

    public IEnumerable<object> SelectedItems2 
    { 
     get 
     { 
      return UpdateSet(); 
     } 
     set 
     { 
      SelectItems(value); 
     } 
    } 

    private IEnumerable<object> UpdateSet() 
    { 
     var listSource = _original as IListSource; 
     IList list = null; 
     if (listSource != null) 
     { 
      list = listSource.GetList(); 
     } 
     var iList = _original as IList; 
     if (list == null && iList != null) 
     { 
      list = iList; 
     } 
     if (list == null) 
     { 
      return _original; 
     } 

     foreach (var item in SelectedItems) 
     { 
      if (!list.Contains(item)) 
      { 
       list.Add(item); 
      } 
     } 
     foreach (var item in _original.ToList()) 
     { 
      if (!SelectedItems.Contains(item)) 
      { 
       list.Remove(item); 
      } 
     } 

     return _original; 

    } 

    private void SelectItems(IEnumerable<object> items) 
    { 
     _original = items; 
     var hashset = new HashSet<object>(); 
     foreach (var item in items) 
     { 
      hashset.Add(item); 
     } 
     for(var i=0;i<Items.Count;i++) 
     { 
      SetSelected(i, hashset.Contains(Items[i])); 
     } 
    } 
} 

基本上我打破所有的規則和假設的IEnumerable隱藏着一個更好吃基於列表的接口,如果這樣做,使用它來改變基礎設置。

最後,我使用EF(實體框架),你不能調用集合屬性的setter,所以我的實體目前看起來像這樣:注意我是如何複製所有列表更改操作,這是完全不必要的,但我確實說這只是第一個工作。

public partial class ParentEntity 
{ 
    public IEnumerable<object> ChildEntities2 
    { 
     get 
     { 
      return new List<object>(ChildEntities); 
     } 
     set 
     { 
      if (value == null) 
      { 
       return; 
      } 
      foreach (var item in ChildEntities.ToList().Where(item => !value.Contains(item))) 
      { 
       ChildEntities.Remove(item); 
      } 

      foreach (var item in value) 
      { 
       var cItem = item as ChildEntity; 
       if (cItem != null) 
       { 
        if (!ChildEntities.Contains(item as ChildEntity)) 
        { 
         ChildEntities.Add(item as ChildEntity); 
        } 
       } 
      }     
     } 
    } 
} 
+0

只是供參考,這是一個真正的黑客,真的只是概念驗證。如果你知道更清潔的方法,我會很感興趣。 – Ian