【发布时间】:2021-10-03 12:43:47
【问题描述】:
这应该是一个重复的问题,但我发布它是因为任何地方的答案都不起作用。
我有一本类型的字典:
private Dictionary<IModule, AssemblyLoadContext> ModuleList = new Dictionary<IModule, AssemblyLoadContext>();
我正在尝试将 IModule 的名称(IModule.Handle,用于实现 IModule 的所有内容)绑定到组合框。
我尝试了很多方法,并在谷歌上搜索了所有答案,但没有任何效果。这显然是你应该这样做的方式:
comboBox1.DataSource = new BindingSource(ModuleList, null);
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";
当我这样做时,我得到一个 RUNTIME 错误:(System.ArgumentException:'无法绑定到新的显示成员。(参数'newDisplayMember')' )
当我尝试交换键和值时,我得到同样的错误:(System.ArgumentException: 'Cannot bind to the new display member. (Parameter 'newDisplayMember')' )
当我尝试其他键/值组合时,我得到随机结果。有时它会显示整个类名(没有帮助),有时它会显示 ToString 表示(重载并且工作正常,除了启动后不更新),有时它什么也不显示或程序在运行时出错。
但是,当模块被加载和卸载时,我尝试过的任何组合都没有真正让 BOX 内容更新(模块本身肯定在加载/卸载并且工作正常)。
这应该在很多年前就可以工作了,我只能想象微软在他们的一次更新中破坏了一些东西,因为预期的方法对我不起作用。
这是使用 .NET core 3.1 模块和 .NET 5.0 应用程序(需要模块工作,因为 microsoft 5.0 exe 不适用于 microsoft 5.0 dll)。
IModule 的重载 ToString 方法返回 Handle,它是一个命名模块的字符串,即 IE“ConsoleModule”,并按预期工作。除了数据绑定之外,其他一切都在工作。
其他人至少可以确认此数据绑定方法在 .NET 5.0 和/或 3.1 中确实有效吗?迅速失去理智。
【问题讨论】:
-
您的意思是您将 BindingSource 的 DataSource 设置为一个空 Dictionary,您尝试将 Items 添加到 Dictionary 并且您没有看到内部 List 更改? -- 请注意,字典是一个复杂对象,要将其用作数据源,它会转换为
List<KeyValuePairs<TKey, TValue>>。此列表不支持列表更改事件。 -- 如果更改 Dictionary 的内容,则必须重置 BindingSource,将 ComboBox 的 DataSource 设置为null,设置DisplayMember(第一)、ValueMember(第二)和DataSource(最后)再次。 -
或者选择一个不是动态字典的数据源。
-
不能直接将 Dictionary 设置为 ComboBox 的 DataSource。你必须设置
[ComboBox].DataSource = [Dictionary].ToList();。这同样适用于 BindingSource,它在内部创建一个 BindingList。类中包含IModule和AssemblyLoadContext类型属性的List<class>可能更容易处理。 -
是的,这当然有效。 Dictionary 已填充,并使用 BindingSource 作为 mediator 设置为 ComboBox 的 DataSource(
DisplayMember和ValueMember应设置在DataSource之前,但这是另一回事)。 -- 如果您不立即填写字典(因此,它是空的)和/或您尝试在之后添加 KeyValuePairs,则会出现不同的情况。在这种情况下,您可以使用类型初始化 BindingSource(例如,[BindingSource] = new BindingSource(typeof(Dictionary<IModule, AssemblyLoadContext>), null);)- 如果需要 - 并在添加一些项目后将其重置。 -
是的,它实际上绑定到
BindingList<KeyValuePair<TKey, TValue>>。如果之后将项目添加到 Dictionary 中,则不会发生任何事情:ComboBox 内容保持不变。 -- 请注意,您可以在[BindingSource].List属性中添加/删除项目(类型为KeyValuePair<TKey, TValue>):这会将项目添加到组合框,但不会影响字典。
标签: c# winforms dictionary data-binding combobox