
อาการ คุณมีฟอร์ม Microsoft Windows ที่ มีตัวควบคุมกล่องรายการหรือComboBoxตัวควบคุม เมื่อคุณผูกListBoxหรือComboBoxกับแหล่งข้อมูล ตัวควบคุมคัดสินค้าในรายการหลายครั้ง
สาเหตุ เมื่อคุณสร้างกล่องรายการหรือเมื่อคุณสร้างComboBoxแบบฟอร์มที่ไม่มีคุณสมบัติBindingContext กล่องรายการหรือComboBoxต้องมีBindingContextเมื่อต้องการคัดลอกข้อมูล ดังนั้น ตัวควบคุมขอให้ ฟอร์มส่งBindingContext แบบฟอร์มสร้างBindingContextและแบบฟอร์มการแจ้งเตือนไปยังตัวควบคุมแรกทำแล้ว กล่องรายการหรือComboBoxได้รับการแจ้งเตือน และตัวควบคุมพยายามปรับปรุงคุณสมบัติDataManager ดังนั้นListBoxหรือComboBoxสร้างสำเนาของรายการแรก เมื่อแบบฟอร์มสร้างBindingContext, ListBoxหรือComboBoxสร้างสำเนาชุดที่สองของรายการ
เมื่อต้องแก้ไขปัญหานี้ ใช้ขั้นตอนต่อไปนี้:
- การตั้งค่าคุณสมบัติBindingContextของตัวควบคุมก่อนที่คุณตั้งค่าการผูกข้อมูลใด ๆ
- การตั้งค่าคุณสมบัติDisplayMemberของตัวควบคุมก่อนที่คุณตั้งค่าคุณสมบัติแหล่งข้อมูล
เมื่อต้องใช้กระบวนงานเหล่านี้ ให้ทำตามขั้นตอนเหล่านี้:
-
รหัสที่มีอยู่ในตัวสร้างแบบฟอร์ม fแทนที่ ด้วยรหัสต่อไปนี้
Dim pt As ProductTypes = New ProductTypes
'Add a ComboBox control to the form.
Dim cb As ComboBox = New ComboBox
Controls.Add(cb)
'Invoke the binding context for the ComboBox.
Dim bc As New BindingContext
cb.BindingContext = bc
'Set the DataSource property and set the DisplayMember property of the ComboBox.
cb.DisplayMember = "Description"
cb.DataSource = pt
หมายเหตุ คุณยังสามารถใช้รหัสนี้สำหรับตัวควบคุมกล่องรายการด้วยการแทนComboBoxด้วยกล่องรายการ.
2.ตรวจแก้จุดบกพร่องเมนู คลิกเริ่มการทำงาน.
วิธีการCopyToนั้นเพียงครั้งเดียว
วิธีการCopyToนั้นเพียงครั้งเดียว
สถานะ Microsoft ยืนยันว่า ปัญหานี้เป็นปัญหาที่เกิดขึ้นกับผลิตภัณฑ์ของ Microsoft ซึ่งมีการระบุไว้ในส่วน"ใช้งาน"
ข้อมูลเพิ่มเติม ขั้นตอนในการทบทวนเกิดลักษณะการทำงาน
1. ใน Microsoft Visual Studio .NET เริ่มต้นโปรแกรมประยุกต์ Windows ใหม่ โดยใช้ Visual Basic .NET หรือ Visual C# .NET
โดยค่าเริ่มต้น Form1 ถูกสร้างขึ้น
โดยค่าเริ่มต้น Form1 ถูกสร้างขึ้น
2. รหัสที่มีอยู่ใน Form1 แทนที่ ด้วยรหัสต่อไปนี้
รหัส.NET Visual Basic
Imports System.Windows.Forms
Class f
Inherits Form
Shared Sub Main()
Application.Run(New f)
End Sub
Private Sub New()
Dim pt As ProductTypes = New ProductTypes
'Add a ComboBox control to the form.
Dim cb As ComboBox = New ComboBox
Controls.Add(cb)
'Set the DataSource property and set the DisplayMember property of the ComboBox.
cb.DataSource = pt
cb.DisplayMember = "Description"
End Sub
End Class
หมายเหตุ คุณยังสามารถใช้รหัสนี้สำหรับตัวควบคุมกล่องรายการด้วยการแทนComboBoxด้วยกล่องรายการ.
3. บนเมนูโครงการคลิกเพิ่มคลาสและจากนั้น คลิกเปิด.
4. แทนรหัสที่มีอยู่ในClass1กับรหัสต่อไปนี้
รหัส.NET Visual Basic
รหัส.NET Visual Basic
Imports System
Imports System.ComponentModel
Imports System.Collections
Imports System.Data
Imports System.Data.SqlClient
Public Class ProductTypes
Implements IList
Implements IEnumerator
Private position As Integer = -1
'List of items
Private _Cache As Hashtable
'List of ordinal pointers to the items
Private _CacheOrdinal As Hashtable
Public Sub New()
_Cache = New Hashtable
_CacheOrdinal = New Hashtable
FillCache()
End Sub
Public Function GetEnumerator() As ProductTypes
position = -1
Console.WriteLine("In type GetEnum..." + Environment.StackTrace)
Return (Me)
End Function
Private Function IGetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
position = -1
Console.WriteLine("In IEnum GetEnum..." + Environment.StackTrace)
Return CType((Me), IEnumerator)
End Function
' IList
Public ReadOnly Property IsFixedSize() As Boolean Implements IList.IsFixedSize
Get
Return (False)
End Get
End Property
' IList
Public ReadOnly Property IsReadOnly() As Boolean Implements IList.IsReadOnly
Get
Return (False)
End Get
End Property
Public Property IItem(ByVal index As Integer) As Object Implements IList.Item
Get
Console.WriteLine("In IList this...")
Return (CType(_Cache(_CacheOrdinal(index)), ProductType))
End Get
Set(ByVal Value As Object)
End Set
End Property
Default Property Item(ByVal pos As Integer) As ProductType
Get
Console.WriteLine("In type this...")
Return (CType(_Cache(_CacheOrdinal(pos)), ProductType))
End Get
Set(ByVal Value As ProductType)
End Set
End Property
' ICollection
Public ReadOnly Property Count() As Integer Implements ICollection.Count
Get
Console.WriteLine("In Count()")
Return (_Cache.Count)
End Get
End Property
' Declare the Reset method that IEnumerator requires:
Public Sub Reset() Implements IEnumerator.Reset
Console.WriteLine("Called reset")
position = -1
End Sub
' Declare the MoveNext method that IEnumerator requires:
Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
If position < _Cache.Count - 1 Then
position = position + 1
Return True
Else
Return False
End If
End Function
Public Function Add(ByVal o As Object) As Integer Implements IList.Add
Return 1
End Function
Public Sub Clear() Implements IList.Clear
End Sub
Public Sub RemoveAt(ByVal i As Integer) Implements IList.RemoveAt
End Sub
Public Sub Remove(ByVal o As Object) Implements IList.Remove
End Sub
Public Function IndexOf(ByVal o As Object) As Integer Implements IList.IndexOf
Return 0
End Function
Public Function Contains(ByVal o As Object) As Boolean Implements IList.Contains
Return False
End Function
Public ReadOnly Property IsSynchronized() As Boolean Implements ICollection.IsSynchronized
Get
Return (False)
End Get
End Property
Public ReadOnly Property SyncRoot() As Object Implements ICollection.SyncRoot
Get
Return (Nothing)
End Get
End Property
Public Sub Insert(ByVal i As Integer, ByVal o As Object) Implements IList.Insert
End Sub
Public ReadOnly Property Current() As ProductType
Get
Return CType(_Cache(_CacheOrdinal(position)), ProductType)
End Get
End Property
' Declare the Current property that IEnumerator requires:
Public ReadOnly Property ICurrent() As Object Implements IEnumerator.Current
Get
Return _Cache(_CacheOrdinal(position))
End Get
End Property
Default Property Item(ByVal productTypeId As String) As ProductType
Get
Return CType((_Cache(productTypeId)), ProductType)
End Get
Set(ByVal Value As ProductType)
End Set
End Property
Public Sub CopyTo(ByVal arr As System.Array, ByVal i As Integer) Implements ICollection.CopyTo
_Cache.CopyTo(arr, i)
Console.WriteLine("Calling copy..." + Environment.StackTrace)
End Sub
Private Sub FillCache()
Dim ordinal As Integer = 0
Dim pType As ProductType = New ProductType
pType.Description = "eric"
pType.ProductTypeId = System.Guid.NewGuid()
_Cache.Add(pType.ProductTypeId, pType)
_CacheOrdinal.Add(ordinal, pType.ProductTypeId)
ordinal = ordinal + 1
Dim pType1 As ProductType = New ProductType
pType1.Description = "nancy"
pType1.ProductTypeId = System.Guid.NewGuid()
_Cache.Add(pType1.ProductTypeId, pType1)
_CacheOrdinal.Add(ordinal, pType1.ProductTypeId)
ordinal = ordinal + 1
End Sub
End Class
Public Class ProductType
Private _ProductTypeId As Guid
Private _Description As String
Public Sub New()
_ProductTypeId = System.Guid.NewGuid()
_Description = Nothing
End Sub
Public Property ProductTypeId() As Guid
Get
Return (_ProductTypeId)
End Get
Set(ByVal Value As Guid)
_ProductTypeId = Value
End Set
End Property
Public Property Description() As String
Get
Return (_Description)
End Get
Set(ByVal Value As String)
_Description = Value
End Set
End Property
End Class
5. คลิกขวาWindowsApplication1และจากนั้น คลิกคุณสมบัติ.
6. ในรายการชนิดของผลผลิตคลิกแอพลิเคชันของคอนโซล.
7. ในรายการเริ่มต้นวัตถุคลิกfและจากนั้น คลิกตกลง.
8. บนเมนูสร้างคลิกสร้างวิธีแก้ไขปัญหา.
9. ตรวจแก้จุดบกพร่องเมนู คลิกเริ่มการทำงาน.
สังเกตผลลัพธ์ในคอนโซล วิธีการCopyToและวิธีการGetEnumeratorเรียกว่าหลายครั้ง ถึงแม้ว่าคุณอาจคาดว่าวิธีการGetEnumeratorการเรียกครั้งที่สองและวิธีการCopyToจะเรียกเพียงครั้งเดียว
สังเกตผลลัพธ์ในคอนโซล วิธีการCopyToและวิธีการGetEnumeratorเรียกว่าหลายครั้ง ถึงแม้ว่าคุณอาจคาดว่าวิธีการGetEnumeratorการเรียกครั้งที่สองและวิธีการCopyToจะเรียกเพียงครั้งเดียว
สำหรับข้อมูลเพิ่มเติม โปรดเยี่ยมชมต่อไปนี้ในการเชื่อมโยงในเว็บไซต์ของ Microsoft สำหรับนักพัฒนาเครือข่าย (MSDN):