2010-06-16 70 views
1

我試圖將列表框的SelectedItem數據綁定到屬性。下面的代碼是一個例子:BindingNavigator綁定列表框的SelectedItem

using System; 
using System.Collections.Generic; 
using System.Windows.Forms; 

namespace BindingFailure 
{ 
static class Program 
{ 
    class OuterObject 
    { 
    public string selected { get; set; } 
    public List<string> strings { get; set; } 
    } 

    public static void Main() 
    { 
    List<OuterObject> objs = new List<OuterObject>() 
    { 
    new OuterObject(), new OuterObject() 
    }; 
    objs[0].strings = new List<string> { "one", "two", "three" }; 
    objs[1].strings = new List<string> { "four", "five", "six" }; 

    Form form = new Form(); 

    BindingSource obs = new BindingSource(objs, null), 
    ibs = new BindingSource(obs, "strings"); 
    BindingNavigator nav = new BindingNavigator(obs); 
    ListBox lbox = new ListBox(); 
    lbox.DataSource = ibs; 
    lbox.DataBindings.Add(new Binding("SelectedItem", obs, "selected")); 

    form.Controls.Add(nav); 
    form.Controls.Add(lbox); 
    lbox.Location = new System.Drawing.Point(30, 30); 

    Application.Run(form); 
    } 
} 
} 

如果你只是選擇一個項目,往前走,選擇一個項目,然後退出,它按預期工作。但是,如果使用導航器在兩個外部對象之間來回切換,則所選項似乎會被不正確的值覆蓋。看來,每次BindingNavigator移動到一個元素時,ListBox都會被告知移動到它的集合中的第一個項目,從而覆蓋綁定到SelectedItem的變量中的任何值。

想法如何解決這個問題?提前致謝。

編輯:這是一個示例項目的存檔,包括一個調試二進制文件。

http://www.mediafire.com/?dzmqmz0mynj

編輯:這是一個基於公認的答案輔助功能:

 public static void Bind(ListControl list, BindingSource outersource, string dataMember) 
     { 
      Binding bindSel = new Binding("SelectedItem", outersource, dataMember); 
      list.DataBindings.Add(bindSel); 

      outersource.CurrentChanged += delegate 
      { 
       list.BeginInvoke(new MethodInvoker(bindSel.ReadValue)); 
      }; 
     } 
+0

我無法重現。它工作得很好,無論我嘗試使用列表框和導航器(除了新建和刪除按鈕)。 – Yegor 2010-06-25 04:46:21

+0

也許它是您使用的.NET版本?我正在使用3.5 ... – Reinderien 2010-06-25 16:59:32

+0

無法使用您提供的代碼重現問題。 C#與.Net 3.5。 「新建」和「移除」按鈕不起作用,但列表似乎使用任何導航按鈕組合都可以很好地填充。你能列出任何其他步驟來幫助重現錯誤,或者可能上傳你的項目到一個文件存儲的地方,所以我們可以看看? – Caladain 2010-06-25 22:17:18

回答

3

這是因爲更新的SelectedItem發生列表框更新之前。因此,第一階段列表框不能從不同的表單記錄「接受」值,因爲它不包含這樣的記錄,並且在列表框項目重新填充後它不能恢復選擇。

解決方案之一是在當前表單記錄更改後,強制SelectedItem綁定重新應用。首先,我們給綁定的名稱:

//lbox.DataBindings.Add(new Binding("SelectedIndex", obs, "Index")); 
var selItemBinding = new Binding("SelectedItem", obs, "selected"); 
lbox.DataBindings.Add(selItemBinding); 

比我們不得不重新綁定(注意的BeginInvoke是必不可少的應用綁定列表框被重新填充後):

obs.CurrentChanged += delegate 
{ 
    form.BeginInvoke(new MethodInvoker(selItemBinding.ReadValue)); 
}; 

您還可以創建簡單的輔助方法將在一次通話中完成所有這些技巧。

+0

完美地工作。謝謝。 – Reinderien 2010-06-27 22:37:50