C# 防止项目在组合框中重复
我使用C# 防止项目在组合框中重复,c#,vb.net,combobox,duplicates,C#,Vb.net,Combobox,Duplicates,我使用vb.net创建了一个用户控件,它继承自ComboBox类 我已经定义了一个名为“ComboType”的属性,它是枚举和一些数组的类型,以及一个名为“ComboPopulate”的方法,它根据ComboType属性填充组合框(我使用了一个选择案例或开关块),还定义了一个名为“SelectedTypeChanged”的事件每当ComboType属性的值更改时发生 问题: 当我将此UI添加到表单并更改ComboType属性时,它会工作,但它会将每个数组插入两次,尽管我已将Me.Items.Cl
vb.net
创建了一个用户控件,它继承自ComboBox
类
我已经定义了一个名为“ComboType”的属性,它是枚举
和一些数组
的类型,以及一个名为“ComboPopulate”的方法,它根据ComboType
属性填充组合框(我使用了一个选择案例或开关块),还定义了一个名为“SelectedTypeChanged”的事件每当ComboType
属性的值更改时发生
问题:
当我将此UI添加到表单并更改ComboType
属性时,它会工作,但它会将每个数组插入两次,尽管我已将Me.Items.Clear()
方法置于ComboPopulate
方法之上
为什么会发生这种情况?解决方案是什么
这是密码
Public Class AdvancedComboBox
Implements INotifyPropertyChanged
Dim Array1() As String = New String() {"item1", "item2", "item3"}
Dim Array2() As String = New String() {"number1", "number2", "city3"}
Dim Array3() As String = New String() {"city1", "city2", "city3"}
Public Event SelectedTypeChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(info As String)
RaiseEvent SelectedTypeChanged(Me, New PropertyChangedEventArgs(info))
End Sub
Public Enum ComboTypes
None
Type1
Type2
Type3
End Enum
Dim _type As ComboTypes
Public Property ComboBoxType As ComboTypes
Get
Return _type
End Get
Set(value As ComboTypes)
_type = value
NotifyPropertyChanged("shomething")
End Set
End Property
Public Sub ComboPopulate()
Me.Items.Clear()
Select Case Me.ComboBoxType
Case ComboTypes.Type1
Items.Clear()
Items.AddRange(Array1)
Case ComboTypes.Type2
Items.Clear(
Items.AddRange(Array2)
Case ComboTypes.Type3
Items.Clear()
Items.AddRange(Array3)
Case ComboTypes.None
Items.Clear()
End Select
End Sub
Private Sub AdvancedComboBox_SelectedTypeChanged(sender As Object, e As PropertyChangedEventArgs) Handles Me.SelectedTypeChanged
ComboPopulate()
End Sub
End Class
您的代码有几个概念上的问题,首先是:
我创建了一个从ComboBox类继承的用户控件。如果它是一个UserControl,它继承自UserControl,但会有一个组合框。如果要从ComboBox继承,则缺少键语句:
Public Class AdvancedComboBox
Inherits ComboBox ' this is missing
Implements INotifyPropertyChanged
代码引用看起来更像是一个继承的控件而不是UserControl,所以我猜测这就是您想要的(通过注释确认)。核心问题在设计器代码中:
Me.ComboEx1.ComboBoxType = WindowsApplication1.ComboEx.ComboTypes.Type2
Me.ComboEx1.FormattingEnabled = True
Me.ComboEx1.Items.AddRange(New Object() {"number1", "number2", "city3"})
将控件添加到表单并设置ComboBoxType
属性时,代码将填充这些项。但是,正如您所看到的,在创建表单时,VS还将这些项直接添加到项中,作为设计器序列化的一部分。由于CBO自身的填充非常奇怪,这是意料之中的。如果/当您在运行时更改ComboBoxType时,它们不会重叠
一个简单的修复方法是默认为“无”,并且仅在运行时设置类型,而不是通过IDE props窗口:
Dim _type As ComboTypes = ComboTypes.None
Sub Form1_Load(....
myAdvCBO.ComboBoxType = ComboTypes.Type2
如果执行此操作,可能需要在IDE窗口中隐藏该属性:
<Browsable(False)>
Public Property ComboBoxType As ComboTypes
点击最后一行的enter键将向控件添加两个新方法:
Public Sub BeginInit() Implements ISupportInitialize.BeginInit
Public Sub EndInit() Implements ISupportInitialize.EndInit
在控件上设置任何属性之前,以及在设置所有属性之后,将调用这些属性EndInit
将允许您撤消VS设计器代码(您可以看到在设计器代码的开头和结尾调用了这些代码)
您的ComboPopulate
已经清除了项,这些项应该可以解决问题
还有一些其他潜在问题:
您的属性设置程序将引发错误事件,因为您没有测试它是否实际更改。如果SelectedTypeChanged
事件应该挂接到ControlDesigner或其他东西,那么额外的事件可能会导致问题,因为VS将重复设置/获取。您的setter可能是:
Set(value As ComboTypes)
If value <> _type Then ' see if it really did change
_type = value
NotifyPropertyChanged("shomething") ' sic
ComboPopulate() ' same as reacting to event
End If
End Set
那么,触发一个事件告诉表单代码它刚刚更改了它刚刚更改的内容有什么意义呢?也许这是我们不了解的更大计划的一部分,但正如所介绍的那样,它并没有增加任何价值
如果这是为了对正在更改的属性做出反应,以便更新项
,那么您确实不需要它。显示代码..*rubs crystal ball*…您可以澄清这实际上是用户控件
还是继承控件。继承控件的代码不正确/不完整,或者UserControl的引用错误。Imports System.ComponentModel是最顶层的文档,“Inherits ComboBox”位于“Public Class AdvancedComboBox”之后的下一行,请原谅我没有编写这些。这是一个继承的控制权我没有足够的声望去投票。成功了。而将属性放在集合中的方法是非常聪明的。谢谢你用了哪种方法?ISupportInitialize?是的,我实现了它,它的方法和你说的一样。但是我怎么知道有像ISupportInitialize这样的接口呢?
Public Sub EndInit() Implements ISupportInitialize.EndInit
ComboPopulate()
End Sub
Set(value As ComboTypes)
If value <> _type Then ' see if it really did change
_type = value
NotifyPropertyChanged("shomething") ' sic
ComboPopulate() ' same as reacting to event
End If
End Set
ComboEx1.ComboBoxType = ComboEx.ComboTypes.Type3