Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Een van de belangrijkste concepten van windows Forms-gegevensbinding is de wijzigingsmelding. Om ervoor te zorgen dat uw gegevensbron en afhankelijke besturingselementen altijd over de meest recente gegevens beschikken, moet u een wijzigingsmelding voor gegevensbinding toevoegen. U wilt er met name voor zorgen dat afhankelijke besturingselementen op de hoogte worden gesteld van wijzigingen die zijn aangebracht in de gegevensbron. De gegevensbron wordt op de hoogte gesteld van wijzigingen die zijn aangebracht in de afhankelijke eigenschappen van een besturingselement.
Er zijn verschillende soorten wijzigingsmeldingen, afhankelijk van het soort gegevensbinding:
Eenvoudige binding, waarbij één besturingselementeigenschap is gebonden aan één exemplaar van een object.
Binding op basis van een lijst, die één besturingselementeigenschap kan bevatten die is gebonden aan de eigenschap van een item in een lijst of een besturingselementeigenschap die afhankelijk is van een lijst met objecten.
Als u bovendien Windows Forms-besturingselementen maakt die u wilt gebruiken voor gegevensbinding, moet u het patroon PropertyNameGewijzigd toepassen op de besturingselementen. Als u een patroon toepast op de besturingselementen, worden wijzigingen in de afhankelijke eigenschap van een besturingselement doorgegeven aan de gegevensbron.
Melding wijzigen voor eenvoudige binding
Voor eenvoudige binding moeten zakelijke objecten een wijzigingsmelding opgeven wanneer de waarde van een afhankelijke eigenschap verandert. U kunt een wijzigingsmelding opgeven door een PropertyNameChanged-gebeurtenis weer te geven voor elke eigenschap van uw bedrijfsobject. Ook moet het bedrijfsobject worden gekoppeld aan besturingselementen met de BindingSource of de voorkeursmethode waarin uw bedrijfsobject de INotifyPropertyChanged-interface implementeert en een PropertyChanged gebeurtenis genereert wanneer de waarde van een eigenschap wordt gewijzigd. Wanneer u objecten gebruikt die de INotifyPropertyChanged-interface implementeren, hoeft u de BindingSource niet te gebruiken om het object aan een besturingselement te binden. Maar het gebruik van de BindingSource wordt aanbevolen.
Melding wijzigen voor binding op basis van een lijst
Windows Forms is afhankelijk van een gebonden lijst om eigenschapswijzigingen en lijstwijzigingen informatie aan gebonden besturingselementen te verstrekken. De eigenschapswijziging is een wijziging van de eigenschapswaarde van een lijstitem en bij de lijstwijziging is er een item aan de lijst toegevoegd of verwijderd. Daarom moeten lijsten die worden gebruikt voor gegevensbinding de IBindingListimplementeren, die beide typen wijzigingsmeldingen biedt. De BindingList<T> is een algemene implementatie van IBindingList en is ontworpen voor gebruik met Windows Forms-gegevensbinding. U kunt een BindingList maken die een bedrijfsobjecttype bevat dat INotifyPropertyChanged implementeert en de lijst de PropertyChanged gebeurtenissen automatisch converteert naar ListChanged gebeurtenissen. Als de afhankelijke lijst geen IBindingListis, moet u de lijst met objecten verbinden met Besturingselementen van Windows Forms met behulp van het onderdeel BindingSource. Het BindingSource-onderdeel verzorgt een conversie van eigenschap naar lijst die vergelijkbaar is met die van de BindingList. Zie How to: Raise Change Notifications Using a BindingSource and the INotifyPropertyChanged Interface (Wijzigingsmeldingen genereren met behulp van een BindingSource en de interface INotifyPropertyChanged) voor meer informatie.
Wijzigingsmelding voor aangepaste besturingselementen
Ten slotte moet u aan de besturingszijde een PropertyNamegewijzigde gebeurtenis beschikbaar maken voor elke eigenschap die is ontworpen om te worden gebonden aan gegevens. De wijzigingen in de eigenschap van het besturingselement worden vervolgens doorgegeven aan de afhankelijke gegevensbron. Zie Het PropertyNameChanged-patroon toepassenvoor meer informatie.
Het patroon PropertyNameChanged toepassen
In het volgende codevoorbeeld ziet u hoe u het patroon PropertyNameGewijzigd toepast op een aangepast besturingselement. Pas het patroon toe wanneer u aangepaste besturingselementen implementeert die worden gebruikt met de gegevensbindingsengine van Windows Forms.
// This class implements a simple user control
// that demonstrates how to apply the propertyNameChanged pattern.
[ComplexBindingProperties("DataSource", "DataMember")]
public class CustomerControl : UserControl
{
private DataGridView dataGridView1;
private Label label1;
private DateTime lastUpdate = DateTime.Now;
public EventHandler DataSourceChanged;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public object DataSource
{
get
{
return this.dataGridView1.DataSource;
}
set
{
if (DataSource != value)
{
this.dataGridView1.DataSource = value;
OnDataSourceChanged();
}
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string DataMember
{
get { return this.dataGridView1.DataMember; }
set { this.dataGridView1.DataMember = value; }
}
private void OnDataSourceChanged()
{
if (DataSourceChanged != null)
{
DataSourceChanged(this, new EventArgs());
}
}
public CustomerControl()
{
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.label1 = new System.Windows.Forms.Label();
this.dataGridView1.ColumnHeadersHeightSizeMode =
System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.ImeMode = System.Windows.Forms.ImeMode.Disable;
this.dataGridView1.Location = new System.Drawing.Point(100, 100);
this.dataGridView1.Size = new System.Drawing.Size(500,500);
this.dataGridView1.TabIndex = 1;
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(50, 50);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(76, 13);
this.label1.TabIndex = 2;
this.label1.Text = "Customer List:";
this.Controls.Add(this.label1);
this.Controls.Add(this.dataGridView1);
this.Size = new System.Drawing.Size(450, 250);
}
}
' This class implements a simple user control
' that demonstrates how to apply the propertyNameChanged pattern.
<ComplexBindingProperties("DataSource", "DataMember")>
Public Class CustomerControl
Inherits UserControl
Private dataGridView1 As DataGridView
Private label1 As Label
Private lastUpdate As DateTime = DateTime.Now
Public DataSourceChanged As EventHandler
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
Public Property DataSource() As Object
Get
Return Me.dataGridView1.DataSource
End Get
Set
If DataSource IsNot Value Then
Me.dataGridView1.DataSource = Value
OnDataSourceChanged()
End If
End Set
End Property
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
Public Property DataMember() As String
Get
Return Me.dataGridView1.DataMember
End Get
Set
Me.dataGridView1.DataMember = Value
End Set
End Property
Private Sub OnDataSourceChanged()
If (DataSourceChanged IsNot Nothing) Then
DataSourceChanged(Me, New EventArgs())
End If
End Sub
Public Sub New()
Me.dataGridView1 = New System.Windows.Forms.DataGridView()
Me.label1 = New System.Windows.Forms.Label()
Me.dataGridView1.ColumnHeadersHeightSizeMode =
System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
Me.dataGridView1.ImeMode = System.Windows.Forms.ImeMode.Disable
Me.dataGridView1.Location = New System.Drawing.Point(19, 55)
Me.dataGridView1.Size = New System.Drawing.Size(550, 150)
Me.dataGridView1.TabIndex = 1
Me.label1.AutoSize = True
Me.label1.Location = New System.Drawing.Point(19, 23)
Me.label1.Name = "label1"
Me.label1.Size = New System.Drawing.Size(76, 13)
Me.label1.TabIndex = 2
Me.label1.Text = "Customer List:"
Me.Controls.Add(Me.label1)
Me.Controls.Add(Me.dataGridView1)
Me.Size = New System.Drawing.Size(650, 300)
End Sub
End Class
De interface INotifyPropertyChanged implementeren
In het volgende codevoorbeeld ziet u hoe u de INotifyPropertyChanged-interface implementeert. Implementeer de interface op zakelijke objecten die worden gebruikt in windows Forms-gegevensbinding. Wanneer deze is geïmplementeerd, communiceert de interface de eigenschapswijzigingen van een bedrijfsobject aan een gebonden besturingselement.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
// Change the namespace to the project name.
namespace binding_control_example
{
// This form demonstrates using a BindingSource to bind
// a list to a DataGridView control. The list does not
// raise change notifications. However the DemoCustomer1 type
// in the list does.
public partial class Form3 : Form
{
// This button causes the value of a list element to be changed.
private Button changeItemBtn = new Button();
// This DataGridView control displays the contents of the list.
private DataGridView customersDataGridView = new DataGridView();
// This BindingSource binds the list to the DataGridView control.
private BindingSource customersBindingSource = new BindingSource();
public Form3()
{
InitializeComponent();
// Set up the "Change Item" button.
this.changeItemBtn.Text = "Change Item";
this.changeItemBtn.Dock = DockStyle.Bottom;
this.changeItemBtn.Height = 100;
//this.changeItemBtn.Click +=
// new EventHandler(changeItemBtn_Click);
this.Controls.Add(this.changeItemBtn);
// Set up the DataGridView.
customersDataGridView.Dock = DockStyle.Top;
this.Controls.Add(customersDataGridView);
this.Size = new Size(400, 200);
}
private void Form3_Load(object sender, EventArgs e)
{
this.Top = 100;
this.Left = 100;
this.Height = 600;
this.Width = 1000;
// Create and populate the list of DemoCustomer objects
// which will supply data to the DataGridView.
BindingList<DemoCustomer1> customerList = new ();
customerList.Add(DemoCustomer1.CreateNewCustomer());
customerList.Add(DemoCustomer1.CreateNewCustomer());
customerList.Add(DemoCustomer1.CreateNewCustomer());
// Bind the list to the BindingSource.
this.customersBindingSource.DataSource = customerList;
// Attach the BindingSource to the DataGridView.
this.customersDataGridView.DataSource =
this.customersBindingSource;
}
// Change the value of the CompanyName property for the first
// item in the list when the "Change Item" button is clicked.
void changeItemBtn_Click(object sender, EventArgs e)
{
// Get a reference to the list from the BindingSource.
BindingList<DemoCustomer1>? customerList =
this.customersBindingSource.DataSource as BindingList<DemoCustomer1>;
// Change the value of the CompanyName property for the
// first item in the list.
customerList[0].CustomerName = "Tailspin Toys";
customerList[0].PhoneNumber = "(708)555-0150";
}
}
// This is a simple customer class that
// implements the IPropertyChange interface.
public class DemoCustomer1 : INotifyPropertyChanged
{
// These fields hold the values for the public properties.
private Guid idValue = Guid.NewGuid();
private string customerNameValue = String.Empty;
private string phoneNumberValue = String.Empty;
public event PropertyChangedEventHandler PropertyChanged;
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
// The constructor is private to enforce the factory pattern.
private DemoCustomer1()
{
customerNameValue = "Customer";
phoneNumberValue = "(312)555-0100";
}
// This is the public factory method.
public static DemoCustomer1 CreateNewCustomer()
{
return new DemoCustomer1();
}
// This property represents an ID, suitable
// for use as a primary key in a database.
public Guid ID
{
get
{
return this.idValue;
}
}
public string CustomerName
{
get
{
return this.customerNameValue;
}
set
{
if (value != this.customerNameValue)
{
this.customerNameValue = value;
NotifyPropertyChanged();
}
}
}
public string PhoneNumber
{
get
{
return this.phoneNumberValue;
}
set
{
if (value != this.phoneNumberValue)
{
this.phoneNumberValue = value;
NotifyPropertyChanged();
}
}
}
}
}
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Drawing
Imports System.Runtime.CompilerServices
Imports System.Windows.Forms
' This form demonstrates using a BindingSource to bind
' a list to a DataGridView control. The list does not
' raise change notifications. However the DemoCustomer1 type
' in the list does.
Public Class Form3
Inherits System.Windows.Forms.Form
' This button causes the value of a list element to be changed.
Private changeItemBtn As New Button()
' This DataGridView control displays the contents of the list.
Private customersDataGridView As New DataGridView()
' This BindingSource binds the list to the DataGridView control.
Private customersBindingSource As New BindingSource()
Public Sub New()
InitializeComponent()
' Set up the "Change Item" button.
Me.changeItemBtn.Text = "Change Item"
Me.changeItemBtn.Dock = DockStyle.Bottom
Me.changeItemBtn.Size = New System.Drawing.Size(100, 100)
AddHandler Me.changeItemBtn.Click, AddressOf changeItemBtn_Click
Me.Controls.Add(Me.changeItemBtn)
' Set up the DataGridView.
customersDataGridView.Dock = DockStyle.Top
Me.Controls.Add(customersDataGridView)
Me.Size = New Size(400, 200)
End Sub
Private Sub Form3_Load(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles Me.Load
Me.Top = 100
Me.Left = 100
Me.Height = 600
Me.Width = 1000
' Create and populate the list of DemoCustomer1 objects
' which will supply data to the DataGridView.
Dim customerList As New BindingList(Of DemoCustomer1)
customerList.Add(DemoCustomer1.CreateNewCustomer())
customerList.Add(DemoCustomer1.CreateNewCustomer())
customerList.Add(DemoCustomer1.CreateNewCustomer())
' Bind the list to the BindingSource.
Me.customersBindingSource.DataSource = customerList
' Attach the BindingSource to the DataGridView.
Me.customersDataGridView.DataSource = Me.customersBindingSource
End Sub
' This event handler changes the value of the CompanyName
' property for the first item in the list.
Private Sub changeItemBtn_Click(ByVal sender As Object, ByVal e As EventArgs)
' Get a reference to the list from the BindingSource.
Dim customerList As BindingList(Of DemoCustomer1) =
CType(customersBindingSource.DataSource, BindingList(Of DemoCustomer1))
' Change the value of the CompanyName property for the
' first item in the list.
customerList(0).CustomerName = "Tailspin Toys"
customerList(0).PhoneNumber = "(708)555-0150"
End Sub
End Class
' This class implements a simple customer type
' that implements the IPropertyChange interface.
Public Class DemoCustomer1
Implements INotifyPropertyChanged
' These fields hold the values for the public properties.
Private idValue As Guid = Guid.NewGuid()
Private customerNameValue As String = String.Empty
Private phoneNumberValue As String = String.Empty
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
' This method is called by the Set accessor of each property.
' The CallerMemberName attribute that is applied to the optional propertyName
' parameter causes the property name of the caller to be substituted as an argument.
Private Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
' The constructor is private to enforce the factory pattern.
Private Sub New()
customerNameValue = "Customer"
phoneNumberValue = "(312)555-0100"
End Sub
' This is the public factory method.
Public Shared Function CreateNewCustomer() As DemoCustomer1
Return New DemoCustomer1()
End Function
' This property represents an ID, suitable
' for use as a primary key in a database.
Public ReadOnly Property ID() As Guid
Get
Return Me.idValue
End Get
End Property
Public Property CustomerName() As String
Get
Return Me.customerNameValue
End Get
Set(ByVal value As String)
If Not (value = customerNameValue) Then
Me.customerNameValue = value
NotifyPropertyChanged()
End If
End Set
End Property
Public Property PhoneNumber() As String
Get
Return Me.phoneNumberValue
End Get
Set(ByVal value As String)
If Not (value = phoneNumberValue) Then
Me.phoneNumberValue = value
NotifyPropertyChanged()
End If
End Set
End Property
End Class
Bindingen synchroniseren
Tijdens de implementatie van gegevensbinding in Windows Forms zijn meerdere besturingselementen gebonden aan dezelfde gegevensbron. In sommige gevallen kan het nodig zijn om extra stappen uit te voeren om ervoor te zorgen dat de afhankelijke eigenschappen van de besturingselementen gesynchroniseerd blijven met elkaar en de gegevensbron. Deze stappen zijn nodig in twee situaties:
Als de gegevensbron geen IBindingListimplementeert en daarom ListChanged gebeurtenissen van het type ItemChangedgenereert.
Als de gegevensbron IEditableObjectimplementeert.
In het vorige geval kunt u een BindingSource gebruiken om de gegevensbron aan de besturingselementen te koppelen. In het laatste geval gebruikt u de BindingSource en handelt u de BindingComplete gebeurtenis af, gevolgd door het aanroepen van EndCurrentEdit op de bijbehorende BindingManagerBase.
Zie de referentiepagina BindingComplete-APIvoor meer informatie over het implementeren van dit concept.
Zie ook
.NET Desktop feedback