디버깅에 문제가있는 이상한 버그가 발생했습니다.왜 WinForms에서 .GetHashCode를 덮어 쓰면 이러한 데이터 바인딩 된 값이 지워 집니까?
Microsoft CAB, DevExpress 구성 요소 및 .Net 3.5를 사용하는 MDI 작업 영역이 있습니다.
사용자가 두 개의 개별 데이터 모델에 바인드 된 UserControl
을 포함하는 두 개의 창을 열면 둘 다 최소화됩니다. 최소화 할 첫 번째 창은 두 번째 창이 최소화되면 바운드 필드가 지워집니다.
데이터 모델의 .Equals
및 .GetHashCode
메소드가 오버라이드되어 두 데이터 모델이 동일하게 간주됩니다. 우리가 그것을 독특하게 바꾸면 우리는 이러한 행동을 취하지 않습니다.
위의 스택 추적에서 EndEditSession()
전화에서, 그것이 : 여기
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
을 호출하는 동안 스택 추적이 [External Code]
시간을 지나갈 때까지 내가 설정 한 OnChange 중단 점은 첫 번째 창에서 변경 메소드를 실행 중입니다.
EndEditSession()
는 해당 UserControl은 데이터 바인딩을 초기화 할 때 채워 도착이
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
샘플 프로젝트에서 실제로 재현 할 수 없었습니다. 샘플에 스마트 파트가 포함 된 전체 MDI 작업 영역을 작성하지 않았기 때문입니다. 내가 작업했던 샘플 코드는 TabControl, 사용자 지정 개체 및 사용자 지정 바인딩 코드가있는 사용자 지정 UserControl이있는 양식입니다. 오늘 다시 시도해보고 큰 샘플 프로젝트에서 문제를 재현 할 수 있는지 확인합니다. – Rachel