مشاركة عبر


كيفية القيام بما يلي: التأكد من بقاء الصف المحدد في جدول فرع في الموضع الصحيح

oftentimes عند العمل مع ربط بيانات في Windows Forms، سوف بيانات dهوplay ما هو تسمى طريقة اصل/فرع أو رئيسي/تفاصيل. ويشير هذا إلى سيناريو ربط بيانات بحيث يتم عرض بيانات من نفس المصدر في عنصري تحكم. يؤدي تغيير تحديد في عنصر تحكم بيانات المعروضة في عنصر التحكم الثاني إلى تغيير. على سبيل المثال، أول عنصر تحكم قد يحتوي على قائمة بالعملاء والثانية قائمة الطلبات المتعلقة بالعميل المحدد في أول عنصر تحكم.

بدءاً من برنامج.NET Framework الإصدار 2.0، عندما كنت dهوplay بيانات في طريقة عرض اصل/فرع قد تحتاج إلى الحصول على إضافية الخطوات للتأكد من أن الصف المحدد حاليا في الجدول الفرع هو عدم يعيد تعيين المعاملة إلى الصف أول من الجدول. في ترتيب إلى للقيام بذلك، عليك أن إلى ذاكرة تخزين مؤقتة لموضع الجدول التابع، وإعادة تعيين بعد تغيير الجدول الأصلي. Typically the فرع يعيد تعيين المعاملة occurs the أول time a حقل in a صف of the الجدول الأصلي التغييرات.

إلى ذاكرة تخزين مؤقت الموضع الحالي للأطفال

  1. قم بتعريف متغير صحيحاً إلى سرد sإلىre التابع موضع ومتغير منطقية إلى sإلىre ما إذا كان إلى ذاكرة التخزين المؤقتة لموضع التابع.

    Private cachedPosition As Integer = - 1
    Private cacheChildPosition As Boolean = True
    
    
    private int cachedPosition = -1;
    private bool cacheChildPosition = true;
    
  2. معالجة ListChangedحدث ربط's CurrencyManagerوالبحث عن ListChangedType Reset.

  3. فحص الموضع الحالي ل CurrencyManager. إذا هو أكبر من الإدخال أول في lهوt (عادة 0)، حفظ إلى متغير.

    Private Sub relatedCM_ListChanged(ByVal sender As Object, _
        ByVal e As ListChangedEventArgs)
        ' Check to see if this is a caching situation.
        If cacheChildPosition AndAlso cachePositionCheckBox.Checked Then
            ' If so, check to see if it is a reset situation, and the current
            ' position is greater than zero.
            Dim relatedCM As CurrencyManager = sender
            If e.ListChangedType = ListChangedType.Reset _
                AndAlso relatedCM.Position > 0 Then
    
                ' If so, cache the position of the child table.
                cachedPosition = relatedCM.Position
            End If
        End If
    
    End Sub
    
    void relatedCM_ListChanged(object sender, ListChangedEventArgs e)
    {
        // Check to see if this is a caching situation.
        if (cacheChildPosition && cachePositionCheckBox.Checked) 
        {
            // If so, check to see if it is a reset situation, and the current
            // position is greater than zero.
            CurrencyManager relatedCM = sender as CurrencyManager;
            if (e.ListChangedType == ListChangedType.Reset && relatedCM.Position > 0)
    
                // If so, cache the position of the child table.
                cachedPosition = relatedCM.Position;
        }
    }
    
  4. مؤشر القائمة الأصل CurrentChangedحدث لإدارة العملة الأصل. في المعالج، قم بتعيين القيمة المنطقية التي تشير إلى أنه هو ليس سيناريو تخزين مؤقت. إذا CurrentChangedحدوث التغيير إلى الأصل هو تغيير موضع lهوt وليس عنصر الالقيمة التغيير.

    ' Handle the current changed event. This event occurs when
    ' the current item is changed, but not when a field of the current
    ' item is changed.
    Private Sub bindingSource1_CurrentChanged(ByVal sender As Object, _
        ByVal e As EventArgs) Handles bindingSource1.CurrentChanged
        ' If the CurrentChanged event occurs, this is not a caching 
        ' situation.
        cacheChildPosition = False
    
    End Sub
    
    void bindingSource1_CurrentChanged(object sender, EventArgs e)
    {
        // If the CurrentChanged event occurs, this is not a caching 
        // situation.
        cacheChildPosition = false;
    }
    

إلى يعيد تعيين المعاملة the فرع موضع

  1. معالجة PositionChangedحدث فرع للتوثيق CurrencyManager.

  2. يعيد تعيين المعاملة فرع جدول موضع إلى موضع المخزنة مؤقتاً بحفظه في إجراء السابق.

    Private Sub relatedCM_PositionChanged(ByVal sender As Object, ByVal e As EventArgs) 
        ' Check to see if this is a caching situation.
        If cacheChildPosition AndAlso cachePositionCheckBox.Checked Then
            Dim relatedCM As CurrencyManager = sender
    
            ' If so, check to see if the current position is 
            ' not equal to the cached position and the cached 
            ' position is not out of bounds.
            If relatedCM.Position <> cachedPosition AndAlso _
                cachedPosition > 0 AndAlso cachedPosition < _
                relatedCM.Count Then
                relatedCM.Position = cachedPosition
                cachedPosition = -1
            End If
        End If
    End Sub
    
    void relatedCM_PositionChanged(object sender, EventArgs e)
    {
        // Check to see if this is a caching situation.
        if (cacheChildPosition && cachePositionCheckBox.Checked)
        {
            CurrencyManager relatedCM = sender as CurrencyManager;
    
            // If so, check to see if the current position is 
            // not equal to the cached position and the cached 
            // position is not out of bounds.
            if (relatedCM.Position != cachedPosition && cachedPosition
                > 0 && cachedPosition < relatedCM.Count)
            {
                relatedCM.Position = cachedPosition;
                cachedPosition = -1;
            }
        }
    }
    

مثال

يوضح المثال التالي كيفية حفظ الموضع الحالي تشغيل CurrencyManager.for جدول تابع وإعادة تعيين الموضع بعد عملية تحرير هو اكتمال في الجدول الأصلي. يتضمن هذا المثال الثاني DataGridViewعناصر تحكم منضمة إلى الثاني الجداول في DataSetاستخدام BindingSourceمكوّن. علاقة هو establهوhed بين الجدولين والعلاقة هو تمت الإضافة إلى DataSet. الموضع في الجدول التابع هو مبدئياً بتعيين إلى الصف الثالث لأغراض العرض التوضيحي.

Imports System
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms



Public Class Form1
    Inherits Form

    Public Sub New() 
        InitializeControlsAndDataSource()

    End Sub

    ' Declare the controls to be used.
    Private WithEvents bindingSource1 As BindingSource
    Private dataGridView1 As DataGridView
    Private WithEvents button1 As Button
    Private dataGridView2 As DataGridView
    Private cachePositionCheckBox As CheckBox
    Public set1 As DataSet


    Private Sub InitializeControlsAndDataSource() 
        ' Initialize the controls and set location, size and 
        ' other basic properties.
        Me.dataGridView1 = New DataGridView()
        Me.bindingSource1 = New BindingSource()
        Me.button1 = New Button()
        Me.dataGridView2 = New DataGridView()
        Me.cachePositionCheckBox = New System.Windows.Forms.CheckBox()
        Me.dataGridView1.ColumnHeadersHeightSizeMode = _
            DataGridViewColumnHeadersHeightSizeMode.AutoSize
        Me.dataGridView1.Dock = DockStyle.Top
        Me.dataGridView1.Location = New Point(0, 20)
        Me.dataGridView1.Size = New Size(292, 170)
        Me.button1.Location = New System.Drawing.Point(18, 175)
        Me.button1.Size = New System.Drawing.Size(125, 23)

        button1.Text = "Clear Parent Field"

        Me.dataGridView2.ColumnHeadersHeightSizeMode = _
            System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
        Me.dataGridView2.Location = New System.Drawing.Point(0, 225)
        Me.dataGridView2.Size = New System.Drawing.Size(309, 130)
        Me.cachePositionCheckBox.AutoSize = True
        Me.cachePositionCheckBox.Checked = True
        Me.cachePositionCheckBox.Location = New System.Drawing.Point(150, 175)
        Me.cachePositionCheckBox.Name = "radioButton1"
        Me.cachePositionCheckBox.Size = New System.Drawing.Size(151, 17)
        Me.cachePositionCheckBox.Text = "Cache and restore position"
        Me.ClientSize = New System.Drawing.Size(325, 420)
        Me.Controls.Add(Me.dataGridView1)
        Me.Controls.Add(Me.cachePositionCheckBox)
        Me.Controls.Add(Me.dataGridView2)
        Me.Controls.Add(Me.button1)

        ' Initialize the data.
        set1 = InitializeDataSet()

        ' Set the data source to the DataSet.
        bindingSource1.DataSource = set1

        'Set the DataMember to the Menu table.
        bindingSource1.DataMember = "Customers"

        ' Add the control data bindings.
        dataGridView1.DataSource = bindingSource1

        ' Set the data source and member for the second DataGridView.
        dataGridView2.DataSource = bindingSource1
        dataGridView2.DataMember = "custOrders"

        ' Get the currency manager for the customer orders binding.
        Dim relatedCM As CurrencyManager = _
            bindingSource1.GetRelatedCurrencyManager("custOrders")

        ' Handle the two events for caching and resetting the position.
        AddHandler relatedCM.ListChanged, AddressOf relatedCM_ListChanged
        AddHandler relatedCM.PositionChanged, AddressOf relatedCM_PositionChanged

        ' Set the position in the child table for demonstration purposes.
        relatedCM.Position = 3

        ' Set cacheing to true in case current changed event
        ' occured on set up.
        cacheChildPosition = True


    End Sub 'InitializeControlsAndDataSource



    ' Establish the data set with two tables and a relationship
    ' between them.
    Private Function InitializeDataSet() As DataSet 
        set1 = New DataSet()
        ' Declare the DataSet and add a table and column.
        set1.Tables.Add("Customers")
        set1.Tables(0).Columns.Add("CustomerID")
        set1.Tables(0).Columns.Add("Customer Name")
        set1.Tables(0).Columns.Add("Contact Name")

        ' Add some rows to the table.
        set1.Tables("Customers").Rows.Add("c1", "Fabrikam, Inc.", _
            "Ellen Adams")
        set1.Tables(0).Rows.Add("c2", "Lucerne Publishing", "Don Hall")
        set1.Tables(0).Rows.Add("c3", "Northwind Traders", "Lori Penor")
        set1.Tables(0).Rows.Add("c4", "Tailspin Toys", "Michael Patten")
        set1.Tables(0).Rows.Add("c5", "Woodgrove Bank", "Jyothi Pai")

        ' Declare the DataSet and add a table and column.
        set1.Tables.Add("Orders")
        set1.Tables(1).Columns.Add("CustomerID")
        set1.Tables(1).Columns.Add("OrderNo")
        set1.Tables(1).Columns.Add("OrderDate")

        ' Add some rows to the table.
        set1.Tables(1).Rows.Add("c1", "119", "10/04/2006")
        set1.Tables(1).Rows.Add("c1", "149", "10/10/2006")
        set1.Tables(1).Rows.Add("c1", "159", "10/12/2006")
        set1.Tables(1).Rows.Add("c2", "169", "10/10/2006")
        set1.Tables(1).Rows.Add("c2", "179", "10/10/2006")
        set1.Tables(1).Rows.Add("c2", "189", "10/12/2006")
        set1.Tables(1).Rows.Add("c3", "122", "10/04/2006")
        set1.Tables(1).Rows.Add("c4", "130", "10/10/2006")
        set1.Tables(1).Rows.Add("c5", "1.29", "10/14/2006")

        Dim dr As New DataRelation("custOrders", _
            set1.Tables("Customers").Columns("CustomerID"), _
            set1.Tables("Orders").Columns("CustomerID"))
        set1.Relations.Add(dr)
        Return set1

    End Function '
    Private cachedPosition As Integer = - 1
    Private cacheChildPosition As Boolean = True

    Private Sub relatedCM_ListChanged(ByVal sender As Object, _
        ByVal e As ListChangedEventArgs)
        ' Check to see if this is a caching situation.
        If cacheChildPosition AndAlso cachePositionCheckBox.Checked Then
            ' If so, check to see if it is a reset situation, and the current
            ' position is greater than zero.
            Dim relatedCM As CurrencyManager = sender
            If e.ListChangedType = ListChangedType.Reset _
                AndAlso relatedCM.Position > 0 Then

                ' If so, cache the position of the child table.
                cachedPosition = relatedCM.Position
            End If
        End If

    End Sub

    ' Handle the current changed event. This event occurs when
    ' the current item is changed, but not when a field of the current
    ' item is changed.
    Private Sub bindingSource1_CurrentChanged(ByVal sender As Object, _
        ByVal e As EventArgs) Handles bindingSource1.CurrentChanged
        ' If the CurrentChanged event occurs, this is not a caching 
        ' situation.
        cacheChildPosition = False

    End Sub

    Private Sub relatedCM_PositionChanged(ByVal sender As Object, ByVal e As EventArgs) 
        ' Check to see if this is a caching situation.
        If cacheChildPosition AndAlso cachePositionCheckBox.Checked Then
            Dim relatedCM As CurrencyManager = sender

            ' If so, check to see if the current position is 
            ' not equal to the cached position and the cached 
            ' position is not out of bounds.
            If relatedCM.Position <> cachedPosition AndAlso _
                cachedPosition > 0 AndAlso cachedPosition < _
                relatedCM.Count Then
                relatedCM.Position = cachedPosition
                cachedPosition = -1
            End If
        End If
    End Sub

    Private count As Integer = 0

    Private Sub button1_Click(ByVal sender As Object, _
        ByVal e As EventArgs) Handles button1.Click
        ' For demo purposes--modifies a value in the first row of the
        ' parent table.
        Dim row1 As DataRow = set1.Tables(0).Rows(0)
        row1(1) = DBNull.Value
    End Sub

    <STAThread()>  _
    Shared Sub Main() 
        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault(False)
        Application.Run(New Form1())

    End Sub
End Class

using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace BT2
{
    public class Form1 : Form
    {
        public Form1()
        {
            InitializeControlsAndDataSource();
        }

        // Declare the controls to be used.
        private BindingSource bindingSource1;
        private DataGridView dataGridView1;
        private Button button1;
        private DataGridView dataGridView2;
        private CheckBox cachePositionCheckBox;
        public DataSet set1;

        private void InitializeControlsAndDataSource()
        {
            // Initialize the controls and set location, size and 
            // other basic properties.
            this.dataGridView1 = new DataGridView();
            this.bindingSource1 = new BindingSource();
            this.button1 = new Button();
            this.dataGridView2 = new DataGridView();
            this.cachePositionCheckBox = new System.Windows.Forms.CheckBox();
            this.dataGridView1.ColumnHeadersHeightSizeMode =
                DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView1.Dock = DockStyle.Top;
            this.dataGridView1.Location = new Point(0, 20);
            this.dataGridView1.Size = new Size(292, 170);
            this.button1.Location = new System.Drawing.Point(18, 175);
            this.button1.Size = new System.Drawing.Size(125, 23);

            button1.Text = "Clear Parent Field";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            this.dataGridView2.ColumnHeadersHeightSizeMode = 
                System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView2.Location = new System.Drawing.Point(0, 225);
            this.dataGridView2.Size = new System.Drawing.Size(309, 130);
            this.cachePositionCheckBox.AutoSize = true;
            this.cachePositionCheckBox.Checked = true;
            this.cachePositionCheckBox.Location = new System.Drawing.Point(150, 175);
            this.cachePositionCheckBox.Name = "radioButton1";
            this.cachePositionCheckBox.Size = new System.Drawing.Size(151, 17);
            this.cachePositionCheckBox.Text = "Cache and restore position";
            this.ClientSize = new System.Drawing.Size(325, 420);
            this.Controls.Add(this.dataGridView1);
            this.Controls.Add(this.cachePositionCheckBox);
            this.Controls.Add(this.dataGridView2);
            this.Controls.Add(this.button1);

            // Initialize the data.
            set1 = InitializeDataSet();

            // Set the data source to the DataSet.
            bindingSource1.DataSource = set1;

            //Set the DataMember to the Menu table.
            bindingSource1.DataMember = "Customers";

            // Add the control data bindings.
            dataGridView1.DataSource = bindingSource1;

            // Set the data source and member for the second DataGridView.
            dataGridView2.DataSource = bindingSource1;
            dataGridView2.DataMember = "custOrders";

            // Get the currency manager for the customer orders binding.
            CurrencyManager relatedCM = 
                bindingSource1.GetRelatedCurrencyManager("custOrders");

            // Set the position in the child table for demonstration purposes.
            relatedCM.Position = 3;

            // Handle the current changed event. This event occurs when
            // the current item is changed, but not when a field of the current
            // item is changed.
            bindingSource1.CurrentChanged += 
                new EventHandler(bindingSource1_CurrentChanged);

            // Handle the two events for caching and resetting the position.
            relatedCM.ListChanged += new ListChangedEventHandler(relatedCM_ListChanged);
            relatedCM.PositionChanged
                += new EventHandler(relatedCM_PositionChanged);

            // Set cacheing to true in case current changed event
            // occured on set up.
            cacheChildPosition = true;
        }


        // Establish the data set with two tables and a relationship
        // between them.
        private DataSet InitializeDataSet()
        {
            set1 = new DataSet();
            // Declare the DataSet and add a table and column.
            set1.Tables.Add("Customers");
            set1.Tables[0].Columns.Add("CustomerID");
            set1.Tables[0].Columns.Add("Customer Name");
            set1.Tables[0].Columns.Add("Contact Name");

            // Add some rows to the table.
            set1.Tables["Customers"].Rows.Add("c1", "Fabrikam, Inc.", "Ellen Adams");
            set1.Tables[0].Rows.Add("c2", "Lucerne Publishing", "Don Hall");
            set1.Tables[0].Rows.Add("c3", "Northwind Traders", "Lori Penor");
            set1.Tables[0].Rows.Add("c4", "Tailspin Toys", "Michael Patten");
            set1.Tables[0].Rows.Add("c5", "Woodgrove Bank", "Jyothi Pai");

            // Declare the DataSet and add a table and column.
            set1.Tables.Add("Orders");
            set1.Tables[1].Columns.Add("CustomerID");
            set1.Tables[1].Columns.Add("OrderNo");
            set1.Tables[1].Columns.Add("OrderDate");

            // Add some rows to the table.
            set1.Tables[1].Rows.Add("c1", "119", "10/04/2006");
            set1.Tables[1].Rows.Add("c1", "149", "10/10/2006");
            set1.Tables[1].Rows.Add("c1", "159", "10/12/2006");
            set1.Tables[1].Rows.Add("c2", "169", "10/10/2006");
            set1.Tables[1].Rows.Add("c2", "179", "10/10/2006");
            set1.Tables[1].Rows.Add("c2", "189", "10/12/2006");
            set1.Tables[1].Rows.Add("c3", "122", "10/04/2006");
            set1.Tables[1].Rows.Add("c4", "130", "10/10/2006");
            set1.Tables[1].Rows.Add("c5", "1.29", "10/14/2006");

            DataRelation dr = new DataRelation("custOrders",
                set1.Tables["Customers"].Columns["CustomerID"],
                set1.Tables["Orders"].Columns["CustomerID"]);
            set1.Relations.Add(dr);
            return set1;
        }
        private int cachedPosition = -1;
        private bool cacheChildPosition = true;

        void relatedCM_ListChanged(object sender, ListChangedEventArgs e)
        {
            // Check to see if this is a caching situation.
            if (cacheChildPosition && cachePositionCheckBox.Checked) 
            {
                // If so, check to see if it is a reset situation, and the current
                // position is greater than zero.
                CurrencyManager relatedCM = sender as CurrencyManager;
                if (e.ListChangedType == ListChangedType.Reset && relatedCM.Position > 0)

                    // If so, cache the position of the child table.
                    cachedPosition = relatedCM.Position;
            }
        }
        void bindingSource1_CurrentChanged(object sender, EventArgs e)
        {
            // If the CurrentChanged event occurs, this is not a caching 
            // situation.
            cacheChildPosition = false;
        }
        void relatedCM_PositionChanged(object sender, EventArgs e)
        {
            // Check to see if this is a caching situation.
            if (cacheChildPosition && cachePositionCheckBox.Checked)
            {
                CurrencyManager relatedCM = sender as CurrencyManager;

                // If so, check to see if the current position is 
                // not equal to the cached position and the cached 
                // position is not out of bounds.
                if (relatedCM.Position != cachedPosition && cachedPosition
                    > 0 && cachedPosition < relatedCM.Count)
                {
                    relatedCM.Position = cachedPosition;
                    cachedPosition = -1;
                }
            }
        }
        int count = 0;
        private void button1_Click(object sender, EventArgs e)
        {
            // For demo purposes--modifies a value in the first row of the
            // parent table.
            DataRow row1 = set1.Tables[0].Rows[0];
            row1[1] = DBNull.Value;

        }

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }


}

إلى اختبار مثال التعليمة البرمجية، اتبع الخطوات التالية:

  1. قم بتشغيل المثال

  2. Make sure the ذاكرة تخزين مؤقت و يعيد تعيين المعاملة موضع فحص صندوق هو selected.

  3. انقر فوق لحقل الأصل مسح زر تسبب تغييرا في حقل في الجدول الأصلي. لاحظ أنه الصف المحدد في فرع لا يتم تغيير الجدول.

  4. إغلاق و تشغيل المثال مرة أخرى. You need إلى do this because the يعيد تعيين المعاملة behavior occurs only on the أول تغيير in the parent صف.

  5. مسح ذاكرة تخزين مؤقت و إعادة تعيين موضع خانة اختيار .

  6. انقر فوق الزر الحقل الأصل مسح. لاحظ أنه الصف المحدد في الجدول التابع التغييرات إلى الصف أول.

التحويل البرمجي للتعليمات البرمجية

يتطلب هذا المثال:

  • مراجع إلى تجميعات النظام System.بيانات، System.رسم، System.Windows.Forms و System.XML.

لمعلومات حول كيفية إلى بنية هذا المثال من سطر الأوامر ل Visual Basicأو #Visual C، راجع الإنشاء من سطر الأوامر (Visual Basic)أو إنشاء سطر الأوامر باستخدام csc.exe. يمكنك أيضاً بناء هذا المثال في Visual Studio عن طريق لصق التعليمات البرمجية في مشروع جديد. لمزيد من المعلومات، راجع: كيفية القيام بما يلي: ترجمة و تشغيل مثال التعليمات برمجية لنماذج Windows الكامل باستخدام ‏‫Visual Studio.

راجع أيضًا:

المهام

كيفية القيام بما يلي: متعدد عناصر التحكم حد تماما ضمان استمرار مصدر بيانات متزامن

المبادئ

ربط بيانات "و" Windows Forms

موارد أخرى

مكوّن BindingSource