我們遇到了一個奇怪的問題,我們在調試時遇到問題。爲什麼覆蓋.GetHashCode在WinForms中清除這些數據綁定值?
我們有一個使用Microsoft CAB,DevExpress組件和.Net 3.5的MDI工作區。
如果用戶在工作區中打開兩個窗口,其中每個窗口都包含綁定到兩個單獨數據模型的UserControl
,那麼將它們兩者最小化,第一個窗口最小化是在第二個窗口最小化時清除綁定字段。
.Equals
和.GetHashCode
數據模型的方法已被覆蓋,因此兩個數據模型都被認爲是相等的。如果我們改變它,所以它們是獨一無二的,我們不會得到這種行爲。
這裏的顯示問題
var a = new MyWindow();
a.DataModel = new SomeClass(123);
a.ShowInMdiWorkspace();
var b = new MyWindow();
b.DataModel = new SomeClass(123);
b.ShowInMdiWorksace();
a.Minimize();
// If SomeClass.GetHashCode() is overwritten to consider two objects
// as equal based on the value passed in, then the data bindings for A
// get cleared on this call. If SomeClass.GetHashCode is unique, then
// this problem does not happen.
b.Minimize();
這裏的調用堆棧當第二窗口被最小化一些示例僞代碼:
在上面的堆棧跟蹤EndEditSession()
調用,它是調用EndEditSession
爲第二個窗口最小化,而在堆棧跟蹤超過[External Code]
t o我已經設置了OnChange斷點,它正在觸發第一個窗口中的更改方法。
EndEditSession()
是定製的東西我們實施這看起來是這樣的
protected void EndEditSession()
{
IBindingValue bv = null;
if (_bindingValues == null)
return;
if (_data != null)
{
foreach (KeyValuePair<string, IBindingValue> kvp in _bindingValues)
{
bv = kvp.Value;
if (bv.IsBindable)
((PropertyManager)bv.Component.BindingContext[_data]).EndCurrentEdit();
}
}
}
_bindingValues
被填充當用戶控件初始化其數據綁定。關鍵字段是綁定控件的名稱,值字段是用於存儲控件本身,名稱,綁定值和默認值的自定義對象。 bv.Component
返回它在我的測試的情況下是一個定製的DevExpress LookupEdit
_data
包含了UserControl
數據模型的綁定設置,控制,我可以驗證它被設置爲實例,以使第二窗口。
我最初的想法是共享BindingContext
,所以錯誤的PropertyManager
正在返回,但是我已驗證兩個窗體和控件的.BindingContext
是分開的。
將UserControl
的兩個單獨副本綁定到兩個單獨的數據模型實例時,如果GetHashCode
方法被覆蓋以使兩個對象被認爲是相等的,它可能會將其綁定混合起來嗎?
我對WinForms綁定系統的內部工作原理不熟悉,或者完全不瞭解CAB的MDI工作空間如何管理。
我的理論是,當第一個窗口最小化時,它將卸載控件以節省內存,然後當第二個窗口最小化管理綁定的內部哈希表時,會錯誤地混淆並運行更新以從中獲取數據第一個最小化窗口(現在是空白)並更新其數據源。這個理論有很多漏洞,但它是我能想到的唯一的東西。
這是我的第一個想法,但同樣的問題仍然發生時,分配每個控件它是自己的'BindingContext' – Rachel
@Rachel你可以提供一個示例項目?似乎沒有足夠的關於你問題的信息。我認爲這個問題不是用'BindingContext'。問題可能出現在你的'_bindingValues'對象中。 – nempoBu4
我實際上無法在示例項目中重現這一點,我認爲這是因爲我沒有在我的示例中使用smartparts創建完整的MDI工作區。我正在使用的示例代碼只是一個帶有TabControl的表單,一個自定義對象以及帶有自定義綁定代碼的自定義UserControl。我今天再試一次,看看我是否可以在更大的示例項目中重現問題。 – Rachel