关键词:
【中文标题】为啥覆盖 .GetHashCode 会清除 WinForms 中的这些数据绑定值?【英文标题】:Why would overwriting .GetHashCode clear these databound values in WinForms?为什么覆盖 .GetHashCode 会清除 WinForms 中的这些数据绑定值? 【发布时间】:2014-08-01 22:50:58 【问题描述】:我们遇到了一个奇怪的错误,我们在调试时遇到了问题。
我们有一个使用 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]
到OnChange我设置的断点,它正在触发 first 窗口中的 change 方法。
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
在 UserControl 初始化其数据绑定时填充。键字段是绑定控件的名称,值字段是自定义对象,其中存储控件本身、控件名称、绑定值和默认值。 bv.Component
返回设置绑定的控件,在我的测试中是自定义的 DevExpress LookupEdit
_data
包含UserControl
的数据模型,我可以验证它是否设置为第二个窗口的实例。
我最初的想法是BindingContext
是共享的,因此返回了错误的PropertyManager
,但是我已经验证了两个表单和控件的.BindingContext
是分开的。
当GetHashCode
方法被覆盖以使这两个对象被视为相等时,是否有可能将UserControl
的两个单独副本绑定到数据模型的两个单独实例时会混淆其绑定?
我不太熟悉 WinForms 绑定系统的内部工作原理,也不了解 CAB 的 MDI 工作区是如何管理的。
我的理论是,当第一个窗口最小化时,它正在卸载控件以节省内存,然后当第二个窗口最小化管理绑定的内部哈希表时,会错误地混淆并运行更新以从第一个最小化窗口(现在为空白)并更新其数据源。这个理论有很多漏洞,但这是我唯一能想到的。
【问题讨论】:
【参考方案1】:我不知道 WinForm 小部件的内部工作原理,但似乎既然您遇到了 overriding equals 的问题,那么您最好解决强>。
如果您需要为自己的目的评估平等:
一种方法是提供您自己的方法来评估相等性,而不是更改默认行为。
如果您的意图是更改小部件处理对象的方式:
一种方法是为您的类创建一个静态对象工厂。工厂可以维护使用弱引用创建的所有对象的集合。弱引用允许 GC 收集对象。然后工厂可以检查以前创建的对象的集合。如果找到匹配项,则返回现有匹配项。如果没有,则创建它。这样,您将拥有一个具有两个相等引用(相同内存)的单个对象,而不是让两个不同的对象评估两个相等(覆盖等于)。
希望这些其他方法之一可以解决您的问题。
【讨论】:
【参考方案2】:BindingContext
对象不与任何其他 BindingContext
共享其字段和属性,因为它的字段和属性不是静态的。
但是,可以有一个BindingContext
对象用于多个控件。
在第一种情况下,如果多个控件具有相同的父级并且没有自己的BindingContext
,则此控件的BindingContext
属性将返回Control.Parent(.Parent...).BindingContext
对象。
在第二种情况下,可能是这样的:
var bindingContext = new BindingContext();
var a = new SomeControl();
var b = new SomeControl();
a.BindingContext = bindingContext;
b.BindingContext = bindingContext;
在第三种情况下,BindingContext
可以用这种方式覆盖。
我不知道你的情况是怎么回事,所以我只能建议在初始化数据绑定之前做这样的事情:
var a = new SomeControl();
var b = new SomeControl();
a.BindingContext = new BindingContext();
b.BindingContext = new BindingContext();
如果这不能解决您的问题,那么您需要检查 _bindingValues
对象的填充情况。可能在填充此对象期间填充了错误的值。
【讨论】:
这也是我的第一个想法,但是在分配每个控件时仍然会出现同样的问题BindingContext
@Rachel 你能提供一个示例项目吗?似乎没有足够的信息来说明您的问题。我认为问题不在于BindingContext
。问题可能出在您的 _bindingValues
对象中。
我实际上无法在示例项目中重现这一点,我认为这是因为我没有在示例中使用智能部件创建完整的 MDI 工作区。我使用的示例代码只是一个带有 TabControl、一个自定义对象和一个带有自定义绑定代码的自定义 UserControl 的表单。我今天再试一次,看看能否在更大的示例项目中重现该问题。为啥我需要覆盖 C# 中的 .Equals 和 GetHashCode [重复]
】为啥我需要覆盖C#中的.Equals和GetHashCode[重复]【英文标题】:WhydoIneedtooverridethe.EqualsandGetHashCodeinC#[duplicate]为什么我需要覆盖C#中的.Equals和GetHashCode[重复]【发布时间】:2013-08-1104:36:31【问题描述】:我正在使用EntityFramework5。在... 查看详情
如果在覆盖 Equals() 时未能覆盖 GetHashCode(),会出现啥问题? [复制]
】如果在覆盖Equals()时未能覆盖GetHashCode(),会出现啥问题?[复制]【英文标题】:WhatcangowrongifonefailstooverrideGetHashCode()whenoverridingEquals()?[duplicate]如果在覆盖Equals()时未能覆盖GetHashCode(),会出现什么问题?[复制]【发布时间】:2009-... 查看详情
覆盖 GetHashCode [重复]
】覆盖GetHashCode[重复]【英文标题】:OverridingGetHashCode[duplicate]【发布时间】:2011-05-1312:46:30【问题描述】:如您所知,GetHashCode返回一个半唯一值,可用于标识集合中的对象实例。作为一种好的做法,建议重写此方法并实现您自... 查看详情
未调用 C#GetHashCode/Equals 覆盖
】未调用C#GetHashCode/Equals覆盖【英文标题】:C#GetHashCode/Equalsoverridenotcalled【发布时间】:2010-11-0622:42:14【问题描述】:我遇到了GetHashCode和Equals的问题,我已经为一个类覆盖了这些问题。我正在使用运算符==来验证两者是否相等... 查看详情
如何在没有任何数字作为字段的情况下覆盖 GetHashCode()?
】如何在没有任何数字作为字段的情况下覆盖GetHashCode()?【英文标题】:HowdoIoverrideGetHashCode()withoutanynumbersasfields?【发布时间】:2017-02-0114:05:17【问题描述】:所有显示如何覆盖Equals(object)和GetHashCode()的资源都使用数字字段来实... 查看详情
包含通用数组的对象的 GetHashCode 覆盖
】包含通用数组的对象的GetHashCode覆盖【英文标题】:GetHashCodeoverrideofobjectcontaininggenericarray【发布时间】:2009-03-1214:08:06【问题描述】:我有一个包含以下两个属性的类:publicintIdget;privateset;publicT[]Valuesget;privateset;我已经做到了I... 查看详情
为啥 GetHashCode 很重要,我们可以在哪里使用它? [复制]
】为啥GetHashCode很重要,我们可以在哪里使用它?[复制]【英文标题】:WhyisGetHashCodeimportantandwherecanweuseit?[duplicate]为什么GetHashCode很重要,我们可以在哪里使用它?[复制]【发布时间】:2011-05-0510:03:30【问题描述】:可能重复:Why... 查看详情
为啥我们需要在对象模型项目中使用 GetHashCode() 函数? [复制]
】为啥我们需要在对象模型项目中使用GetHashCode()函数?[复制]【英文标题】:WhydoweneedGetHashCode()functionintheObjectModelProject?[duplicate]为什么我们需要在对象模型项目中使用GetHashCode()函数?[复制]【发布时间】:2012-06-2116:07:59【问题... 查看详情
正确实施 GetHashCode [重复]
】正确实施GetHashCode[重复]【英文标题】:ImplementingGetHashCodecorrectly[duplicate]【发布时间】:2012-02-1901:16:24【问题描述】:我想听听社区的意见,我应该如何为我的对象实现GetHashCode(或覆盖它)。我知道如果我覆盖equals方法,我... 查看详情
如何在Castle.Core中实现IProxyGenerationHook的类中实现Equals和GetHashCode的覆盖方法?
...如何在Castle.Core中实现IProxyGenerationHook的类中实现Equals和GetHashCode的覆盖方法?【英文标题】:HowtoimplementtheoverridemethodsofEqualsandGetHashCodeinaclassthatimplementsIProxyGenerationHookinCastle.Core?【发布时间】:2021-04-1817:06:39【问题描述】:阅读t... 查看详情
为啥清除列表会清除第一个? [复制]
】为啥清除列表会清除第一个?[复制]【英文标题】:Whydoesclearingalistclearthefirst?[duplicate]为什么清除列表会清除第一个?[复制]【发布时间】:2021-12-0911:38:16【问题描述】:我编写了这个小例子,以便您了解我的问题。我制作了... 查看详情
gitmerge为啥会覆盖
参考技术A覆盖啥。merge就是合并,在没冲突的时候,会自动merge。有啥问题。本回答被提问者和网友采纳 查看详情
为啥覆盖会更改列名
】为啥覆盖会更改列名【英文标题】:Whydoesoverridingchangecolumnnames为什么覆盖会更改列名【发布时间】:2012-09-2601:15:44【问题描述】:我使用的是rev监听器的默认实现,正如预期的那样,我的REVINFO表中的列是:revtstmp和rev。但是... 查看详情
为啥 UIButton 会覆盖 UITapGestureRecognizer?
】为啥UIButton会覆盖UITapGestureRecognizer?【英文标题】:WhyisaUIButtonisoverridingUITapGestureRecognizer?为什么UIButton会覆盖UITapGestureRecognizer?【发布时间】:2010-09-3023:41:49【问题描述】:我有一个带有2个子视图的父UIView:一个UIButton和一... 查看详情
自定义类型 GetHashCode [重复]
】自定义类型GetHashCode[重复]【英文标题】:CustomtypeGetHashCode[duplicate]【发布时间】:2011-06-3021:46:17【问题描述】:可能重复:WhatisthebestalgorithmforanoverriddenSystem.Object.GetHashCode?我需要为由三个字符串组成的类型覆盖GetHashCode方法。... 查看详情
为啥清除 Derived Data 会清除 Xcode 中的各种错误?
】为啥清除DerivedData会清除Xcode中的各种错误?【英文标题】:WhydoesclearingDerivedDataclearupvariouserrorsinXcode?为什么清除DerivedData会清除Xcode中的各种错误?【发布时间】:2016-12-1620:15:01【问题描述】:通常,人们在xcode中遇到各种问... 查看详情
linux清除ssh重新生成会覆盖原有的嘛
参考技术A会。在linux系统中清除ssh文件后,如果需要恢复该文件的使用,可以对其进行重新生成,并且该文件会覆盖掉之前原有的旧文件。 查看详情
覆盖 isHighlighted 仍然会改变 UIControlState - 为啥?
】覆盖isHighlighted仍然会改变UIControlState-为啥?【英文标题】:OverridingisHighlightedstillchangesUIControlState-why?覆盖isHighlighted仍然会改变UIControlState-为什么?【发布时间】:2018-08-1318:09:16【问题描述】:在一个UIControl中,如果我重写isHi... 查看详情