Российский Государственный Технологический Университет им. К.Э. Циолковского
Опубликован: 02.03.2007 | Доступ: свободный | Студентов: 5678 / 802 | Оценка: 3.96 / 3.45 | Длительность: 27:04:00
ISBN: 978-5-9556-0086-4
Лекция 18:

Основы ADO .NET

< Лекция 17 || Лекция 18: 123456789101112

Изменение данных в DataTable и состояние строки таблицы

Основной контроль за изменениями данных в таблице возлагается на строки – объекты класса DataRow.

Для строки определены несколько состояний, которые объявлены в перечислении RowState. Контроль за сохраняемой в строках таблицы информацией обеспечивается посредством определения состояния строки, которое обеспечивается одноименным ( RowState ) свойством – членом класса DataRow.

Состояние Описание
Unchanged Строка не изменялась со времени загрузки при помощи метода Fill() либо с момента вызова метода AcceptChanges()
Added Строка была добавлена в таблицу, но метод AcceptChanges() еще не вызывался
Deleted Строка была удалена из таблицы, но метод AcceptChanges() еще не вызывался
Modified Некоторые из полей строки были изменены, но метод AcceptChanges() еще не вызывался
Detached Строка НЕ ЯВЛЯЕТСЯ ЭЛЕМЕНТОМ КОЛЛЕКЦИИ DataRows. Ее создали от имени таблицы, но не подключили

Пример. Создание таблицы, работа с записями

using System;
 using System.Data;

 namespace Rolls01
 {

 // Работа с таблицей: 
 // определение структуры таблицы,
 // сборка записи (строки таблицы),
 // добавление новой записи в таблицу,
 // индексация записей,
 // выбор значения поля в строке,
 // изменение записи.   

 public class RollsData
 {
 	public DataTable rolls;
 	int rollIndex;
 	
     public RollsData()
     {
     rollIndex = 0;
     // Создается объект "таблица".
     rolls = new DataTable("Rolls");
     // Задаются и подсоединяются столбики, которые определяют тип таблицы.
     // Ключевой столбец.
     DataColumn dc = rolls.Columns.Add("nRoll",typeof(Int32));
     dc.AllowDBNull = false;
     dc.Unique = true;
     //rolls.PrimaryKey = dc;
     // Прочие столбцы, значения которых определяют физические
     // характеристики объектов. 
     rolls.Columns.Add("Victim",typeof(Int32));
     // Значения координат.
     rolls.Columns.Add("X", typeof(Single));
     rolls.Columns.Add("Y", typeof(Single));
     // Старые значения координат.
     rolls.Columns.Add("lastX", typeof(Single));
     rolls.Columns.Add("lastY", typeof(Single));
     // Составляющие цвета.
     rolls.Columns.Add("Alpha", typeof(Int32));
     rolls.Columns.Add("Red", typeof(Int32));
     rolls.Columns.Add("Green", typeof(Int32));
     rolls.Columns.Add("Blue", typeof(Int32));
     }

 	// Добавление записи в таблицу.
 	public void AddRow(int key,
 		             int victim,
 			       float x,
 			       float y,
 			       float lastX,
 			       float lastY,
 			       int alpha,
 			       int red,
 			       int green,
 			       int blue)
 	{
             // Новая строка создается от имени таблицы,
             // тип которой определяется множеством ранее
             // добавленных к таблице столбцов. Подобным образом
             // созданная строка содержит кортеж ячеек
             // соответствующего типа.

 		DataRow dr = rolls.NewRow();
             // Заполнение ячеек строки.
 		dr["nRoll"] = key;
 		dr["Victim"] = victim;
 		dr["X"] = x;
 		dr["Y"] = y;
 		dr["lastX"] = lastX;
 		dr["lastY"] = lastY;
 		dr["Alpha"] = alpha;
 		dr["Red"] = red;
 		dr["Green"] = green;
 		dr["Blue"] = blue;
             // Созданная и заполненная строка
             // подсоединяется к таблице.
 	      rolls.Rows.Add(dr);
 	}

 	// Выборка значений очередной строки таблицы.
 	// Ничего особенного. Для доступа к записи (строке) используются
 	// выражения индексации по отношению к множеству Rows.
 	// Для доступа к полю выбранной записи используются
               // "индексаторы-идентификаторы". 
 	public void NextRow(ref rPoint p)
 	{
 	p.index = (int)rolls.Rows[rollIndex]["nRoll"];
       p.victim = (int)rolls.Rows[rollIndex]["Victim"];
       p.p.X =   (float)rolls.Rows[rollIndex]["X"];
       p.p.Y =   (float)rolls.Rows[rollIndex]["Y"];
       p.lastXdirection  =  (float)rolls.Rows[rollIndex]["lastX"];
 	p.lastYdirection  =  (float)rolls.Rows[rollIndex]["lastY"];
 	p.c.alpha =   (int)rolls.Rows[rollIndex]["Alpha"];
 	p.c.red =   (int)rolls.Rows[rollIndex]["Red"];
 	p.c.green =   (int)rolls.Rows[rollIndex]["Green"];
 	p.c.blue =   (int)rolls.Rows[rollIndex]["Blue"];
 	p.cp.alpha = p.c.alpha – 50;
 	p.cp.red = p.c.red – 10;
 	p.cp.green = p.c.green – 10;
 	p.cp.blue = p.c.blue – 10;
       rollIndex++; // Изменили значение индекса строки.

 	 if (rollIndex == rolls.Rows.Count) rollIndex = 0;		
 	}

     // Та же выборка, но в параметрах дополнительно указан индекс записи.  
 	public void GetRow(ref rPoint p, int key)
 	{
 	  p.index = (int)rolls.Rows[key]["nRoll"];
 	  p.victim = (int)rolls.Rows[key]["Victim"];
 	  p.p.X =   (float)rolls.Rows[key]["X"];
 	  p.p.Y =   (float)rolls.Rows[key]["Y"];
 	  p.lastXdirection  =  (float)rolls.Rows[key]["lastX"];
 	  p.lastYdirection  =  (float)rolls.Rows[key]["lastY"];
 	  p.c.alpha =   (int)rolls.Rows[key]["Alpha"];
 	  p.c.red =     (int)rolls.Rows[key]["Red"];
 	  p.c.green =   (int)rolls.Rows[key]["Green"];
 	  p.c.blue =    (int)rolls.Rows[key]["Blue"];
 	  p.cp.alpha = p.c.alpha – 50;
 	  p.cp.red = p.c.red – 10;
 	  p.cp.green = p.c.green – 10;
 	  p.cp.blue = p.c.blue – 10;
 	  if (rollIndex == rolls.Rows.Count) rollIndex = 0;
  	}

 	// Изменяется значение координат и статуса точки.
       // Значение порядкового номера объекта-параметра используется
       // в качестве первого индексатора, имя столбца – в
       // качестве второго. Скорость выполнения операции присваивания
       // значения ячейке оставляет желать лучшего.       
 	public void SetXYStInRow(rPoint p)
 	{
 	 rolls.Rows[p.index]["X"] = p.p.X;
 	 rolls.Rows[p.index]["Y"] = p.p.Y;
        rolls.Rows[p.index]["lastX"] = p.lastXdirection;
 	 rolls.Rows[p.index]["lastY"] = p.lastYdirection;
        rolls.Rows[p.index]["Victim"] = p.victim;
 	}
     
 	public void ReSetRowIndex()
 	{
 		rollIndex = 0;
 	}

 }
 }
Листинг 18.3.

Relations

В классе DataSet определяется свойство Relations – набор объектов – представителей класса DataRelations. Каждый такой объект определяет связи между составляющими объект DataSet объектами DataTable (таблицами). Если в DataSet более одного набора DataTable, набор DataRelations будет содержать несколько объектов типа DataRelation. Каждый объект определяет связи между таблицами – DataTable. Таким образом, в объекте DataSet реализуется полный набор элементов для управления данными, включая сами таблицы, ограничения и отношения между таблицами.

Constraints

Объекты – представители класса Constraint в наборе Constraints объекта DataTable позволяет задать на множестве объектов DataTable различные ограничения. Например, можно создать объект Constraint, гарантирующий, что значение поля или нескольких полей будут уникальны в пределах DataTable.

DataView

Объекты – представители класса DataView НЕ ПРЕДНАЗНАЧЕНЫ для организации визуализации объектов DataTable.

Их назначение – простой последовательный доступ к строкам таблицы. Объекты DataView являются средством перебора записей таблицы. При обращении ЧЕРЕЗ объект DataView к таблице получают данные, которые хранятся в этой таблице.

DataView нельзя рассматривать как таблицу. DataView не может обеспечить представление таблиц. Также DataView не может обеспечить исключения и добавления столбцов. Таким образом, DataView НЕ является средством преобразования исходной информации, зафиксированной в таблице.

После создания объекта DataView и его настройки на конкретную таблицу появляется возможность перебора записей, их фильтрации, поиска и сортировки.

DataView предоставляет средства динамического представления набора данных, к которому можно применить различные вырианты сортировки и фильтрации на основе критериев, обеспечиваемых базой данных.

Класс DataView обладает большим набором свойств, методов и событий, что позволяет с помощью объекта – представителя класса DataView создавать различные представления данных, содержащихся в DataTable.

Используя этот объект, можно представлять содержащиеся в таблице данные в соответствии с тем или иным порядком сортировки, а также организовать различные варианты фильтрации данных.

DataView предоставляет динамический взгляд на содержимое таблицы в зависимости от установленного в таблице порядка представления и вносимых в таблицы изменений.

Функционально реализация DataView отличается от метода Select, определенного в DataTable, который возвращает массив DataRow (строк).

Для управления установками представления для всех таблиц, входящих в DataSet, используется объект – представитель класса DataViewManager.

DataViewManager предоставляет удобный способ управления параметрами настройки представления по умолчанию для каждой таблицы.

Примеры использования DataView

Для организации просмотра информации, сохраняемой объектом-представителем класса DataTable через объект – представитель класса DataView, этот объект необходимо связать с таблицей.

Таким образом, в приложении создается (независимый!) вьюер, который связывается с таблицей.

Итак, имеем

DataTable tbl = new DataTable("XXX"); // Объявлен и определен объект "таблица".
 DataView vie; // Ссылка на вьюер.

 vie = new DataView(); // Создали...
 vie.Table = tbl; // Привязали таблицу к вьюеру.

 // Можно и так...
 vie = new DataView(tbl); // Создали и сразу привязали...

Управление вьюером также осуществляется посредством различных достаточно простых манипуляций, включая изменение свойств объекта. Например, сортировка включается следующим образом:

// Предполагается наличие кнопочных переключателей,
 // в зависимости от состояния которых в свойстве Sort
 // вьюера выставляется в качестве значения имя того или
 // иного столбца. Результат сортировки становится виден
 // непосредственно после передачи информации объекту,
 // отвечающему за демонстрацию таблицы (rpDataGrid).

 if (rBN.Checked) rd.view.Sort = "nRoll";	
 if (rBX.Checked) rd.view.Sort = "X";
 if (rBY.Checked) rd.view.Sort = "Y";

 this.rpDataGrid.DataSource = rd.view;

Следующий пример кода демонстрирует возможности поиска, реализуемые объектом – представителем класса DataView. Сортировка обеспечивается вариантами методов Find и FindRows, которые способны в различной реализации воспринимать отдельные значения или массивы значений.

Поиск информации проводится по столбцам, предварительно перечисленным в свойстве Sort. При неудовлетворительном результате поиска метод Find возвращает отрицательное значение, метод FindRows – нулевое.

В случае успеха метода Sort возвращается индекс первой найденной записи. По этому индексу можно получить непосредственный доступ к записи:

// Выставили значение индекса 
 int findIndex = –1; 
 :::::
 // Поиск в строке по полю "nRoll" (целочисленный столбец)
 rd.view.Sort = "nRoll";
 try
 {
 // Проверка на соответствие типа.
 int.Parse(this.findTtextBox.Text);
 // Сам поиск.
 findIndex = rd.view.Find(this.findTtextBox.Text); 
 }
 catch (Exception e1)
 {
 this.findTtextBox.Text = "Integer value expected...";
 }
 }
 :::::
 // Проверка результатов.
 if (findIndex == –1)
 {
 this.findTtextBox.Text = "Row not found: " + this.findTtextBox.Text;
 }
 else
 {
 this.findTtextBox.Text =
 "Yes :" + rd.view[findIndex]["nRoll"].ToString() +
 ","     + rd.view[findIndex]["X"].ToString() +
 ","     + rd.view[findIndex]["Y"].ToString();
 }
Листинг 18.4.

Применение метода FindRows. В случае успешного завершения поиска возвращается массив записей, элементы которого могут быть выбраны посредством цикла foreach:

// Массив для получения результатов поиска 
 DataRowView[] rows; 
 :::::
 // Поиск в строке по полю "nRoll" (целочисленный столбец)
 rd.view.Sort = "nRoll";
 try
 {
 // Проверка на соответствие типа.
 int.Parse(this.findTtextBox.Text);
 // Сам поиск. Возвращается массив rows.
 rows = rd.view.FindRows(this.findTtextBox.Text); 
 }
 catch (Exception e1)
 {
 this.findTtextBox.Text = "Integer value expected...";
 }
 }
 :::::
 // Проверка результатов.
 if (rows.Length == 0)
 {
 this.findTtextBox.Text = "No rows found: " + this.findTtextBox.Text;
 }
 else
 {
  foreach (DataRowView row in rows)
 {
 this.findTtextBox.Text =
 row["nRoll"].ToString() +
 ","     + row["X"].ToString() +
 ","     + row["Y"].ToString();
 }
 }
Листинг 18.5.

В примере демонстрируется взаимодействие автономной таблицы и "заточенного" под нее вьюера. Записи в таблицу можно добавлять как непосредственно, так и через вьюер. При этом необходимо совершать некоторое количество дополнительных действий. Через вьюер же организуется поиск записей.

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

 namespace Lights01
 {
 public class DataViewForm : System.Windows.Forms.Form
 {
 private System.ComponentModel.Container components = null;

 DataTable dt;         // Таблица.
 DataColumn c1, c2;    // Столбцы таблцы.
 DataRow dr;           // Строка таблицы.
 DataView dv;          // Вьюер таблицы.
 DataRowView rv;       // Вьюер строки таблицы.

 int currentCounter;   // Счетчик текущей строки для вьюера таблицы.

 private System.Windows.Forms.DataGrid dG;
 private System.Windows.Forms.DataGrid dGforTable;
 private System.Windows.Forms.Button buttPrev;
 private System.Windows.Forms.Button buttFirst;
 private System.Windows.Forms.Button buttLast;
 private System.Windows.Forms.Button buttonFind;
 private System.Windows.Forms.TextBox demoTextBox;
 private System.Windows.Forms.TextBox findTextBox;
 private System.Windows.Forms.Button buttonAdd;
 private System.Windows.Forms.Button buttonAcc;
 private System.Windows.Forms.GroupBox groupBox1;
 private System.Windows.Forms.GroupBox groupBox2;
 private System.Windows.Forms.Button buttNext;

 public DataViewForm()
 {
 InitializeComponent();
 CreateTable();
 dG.DataSource = dv;
 dGforTable.DataSource = dt;
 currentCounter = 0;
 rv = dv[currentCounter];
 demoTextBox.Text = rv["Item"].ToString();
 }

 protected override void Dispose( bool disposing )
 {
 if( disposing )
 {
 	if(components != null)
 	{
 		components.Dispose();
 	}
 }
 base.Dispose( disposing );
 }

 #region Windows Form Designer generated code

 // Required method for Designer support – do not modify
 // the contents of this method with the code editor.

 private void InitializeComponent()
 {
 this.dG = new System.Windows.Forms.DataGrid();
 this.demoTextBox = new System.Windows.Forms.TextBox();
 this.buttPrev = new System.Windows.Forms.Button();
 this.buttNext = new System.Windows.Forms.Button();
 this.buttFirst = new System.Windows.Forms.Button();
 this.buttLast = new System.Windows.Forms.Button();
 this.findTextBox = new System.Windows.Forms.TextBox();
 this.buttonFind = new System.Windows.Forms.Button();
 this.buttonAdd = new System.Windows.Forms.Button();
 this.dGforTable = new System.Windows.Forms.DataGrid();
 this.buttonAcc = new System.Windows.Forms.Button();
 this.groupBox1 = new System.Windows.Forms.GroupBox();
 this.groupBox2 = new System.Windows.Forms.GroupBox();
((System.ComponentModel.ISupportInitialize)(this.dG)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.dGforTable)).BeginInit();
 this.groupBox1.SuspendLayout();
 this.groupBox2.SuspendLayout();
 this.SuspendLayout();
 // 
 // dG
 // 
 this.dG.DataMember = "";
 this.dG.HeaderForeColor = System.Drawing.SystemColors.ControlText;
 this.dG.Location = new System.Drawing.Point(8, 80);
 this.dG.Name = "dG";
 this.dG.Size = new System.Drawing.Size(280, 128);
 this.dG.TabIndex = 0;
 this.dG.MouseDown +=
    new System.Windows.Forms.MouseEventHandler(this.dG_MouseDown);
 // 
 // demoTextBox
 // 
 this.demoTextBox.Location = new System.Drawing.Point(152, 48);
 this.demoTextBox.Name = "demoTextBox";
 this.demoTextBox.Size = new System.Drawing.Size(128, 20);
 this.demoTextBox.TabIndex = 1;
 this.demoTextBox.Text = "";
 // 
 // buttPrev
 // 
 this.buttPrev.Location = new System.Drawing.Point(189, 16);
 this.buttPrev.Name = "buttPrev";
 this.buttPrev.Size = new System.Drawing.Size(25, 23);
 this.buttPrev.TabIndex = 2;
 this.buttPrev.Text = "<–";
 this.buttPrev.Click += new System.EventHandler(this.buttPrev_Click);
 // 
 // buttNext
 // 
 this.buttNext.Location = new System.Drawing.Point(221, 16);
 this.buttNext.Name = "buttNext";
 this.buttNext.Size = new System.Drawing.Size(25, 23);
 this.buttNext.TabIndex = 3;
 this.buttNext.Text = "–>";
 this.buttNext.Click += new System.EventHandler(this.buttNext_Click);
 // 
 // buttFirst
 // 
 this.buttFirst.Location = new System.Drawing.Point(157, 16);
 this.buttFirst.Name = "buttFirst";
 this.buttFirst.Size = new System.Drawing.Size(25, 23);
 this.buttFirst.TabIndex = 4;
 this.buttFirst.Text = "<<";
 this.buttFirst.Click += new System.EventHandler(this.buttFirst_Click);
 // 
 // buttLast
 // 
 this.buttLast.Location = new System.Drawing.Point(253, 16);
 this.buttLast.Name = "buttLast";
 this.buttLast.Size = new System.Drawing.Size(25, 23);
 this.buttLast.TabIndex = 5;
 this.buttLast.Text = ">>";
 this.buttLast.Click += new System.EventHandler(this.buttLast_Click);
 // 
 // findTextBox
 // 
 this.findTextBox.Location = new System.Drawing.Point(8, 48);
 this.findTextBox.Name = "findTextBox";
 this.findTextBox.Size = new System.Drawing.Size(128, 20);
 this.findTextBox.TabIndex = 6;
 this.findTextBox.Text = "";
 // 
 // buttonFind
 // 
 this.buttonFind.Location = new System.Drawing.Point(88, 16);
 this.buttonFind.Name = "buttonFind";
 this.buttonFind.Size = new System.Drawing.Size(48, 23);
 this.buttonFind.TabIndex = 7;
 this.buttonFind.Text = "Find";
 this.buttonFind.Click += new System.EventHandler(this.buttonFind_Click);
 // 
 // buttonAdd
 // 
 this.buttonAdd.Location = new System.Drawing.Point(8, 16);
 this.buttonAdd.Name = "buttonAdd";
 this.buttonAdd.Size = new System.Drawing.Size(40, 23);
 this.buttonAdd.TabIndex = 8;
 this.buttonAdd.Text = "Add";
 this.buttonAdd.Click += new System.EventHandler(this.buttonAdd_Click);
 // 
 // dGforTable
 // 
 this.dGforTable.DataMember = "";
 this.dGforTable.HeaderForeColor = System.Drawing.SystemColors.ControlText;
 this.dGforTable.Location = new System.Drawing.Point(8, 24);
 this.dGforTable.Name = "dGforTable";
 this.dGforTable.Size = new System.Drawing.Size(272, 120);
 this.dGforTable.TabIndex = 9;
 // 
 // buttonAcc
 // 
 this.buttonAcc.Location = new System.Drawing.Point(8, 152);
 this.buttonAcc.Name = "buttonAcc";
 this.buttonAcc.Size = new System.Drawing.Size(40, 23);
 this.buttonAcc.TabIndex = 10;
 this.buttonAcc.Text = "Acc";
 this.buttonAcc.Click += new System.EventHandler(this.buttonAcc_Click);
 // 
 // groupBox1
 // 
 this.groupBox1.Controls.Add(this.buttonAcc);
 this.groupBox1.Controls.Add(this.dGforTable);
 this.groupBox1.Location = new System.Drawing.Point(6, 8);
 this.groupBox1.Name = "groupBox1";
 this.groupBox1.Size = new System.Drawing.Size(298, 184);
 this.groupBox1.TabIndex = 11;
 this.groupBox1.TabStop = false;
 this.groupBox1.Text = "Таблица как она есть  ";
 // 
 // groupBox2
 // 
 this.groupBox2.Controls.Add(this.buttPrev);
 this.groupBox2.Controls.Add(this.buttonFind);
 this.groupBox2.Controls.Add(this.buttFirst);
 this.groupBox2.Controls.Add(this.buttLast);
 this.groupBox2.Controls.Add(this.demoTextBox);
 this.groupBox2.Controls.Add(this.buttNext);
 this.groupBox2.Controls.Add(this.dG);
 this.groupBox2.Controls.Add(this.buttonAdd);
 this.groupBox2.Controls.Add(this.findTextBox);
 this.groupBox2.Location = new System.Drawing.Point(8, 200);
 this.groupBox2.Name = "groupBox2";
 this.groupBox2.Size = new System.Drawing.Size(296, 216);
 this.groupBox2.TabIndex = 12;
 this.groupBox2.TabStop = false;
 this.groupBox2.Text = "Вид через вьюер";
 // 
 // DataViewForm
 // 
 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
 this.ClientSize = new System.Drawing.Size(312, 421);
 this.Controls.Add(this.groupBox2);
 this.Controls.Add(this.groupBox1);
 this.Name = "DataViewForm";
 this.Text = "DataViewForm";
 ((System.ComponentModel.ISupportInitialize)(this.dG)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.dGforTable)).EndInit();
 this.groupBox1.ResumeLayout(false);
 this.groupBox2.ResumeLayout(false);
 this.ResumeLayout(false);

 }
 #endregion

 private void CreateTable()
 {

 // Создается таблица. 
 dt = new DataTable("Items");

 // Столбцы таблицы...
 // Имя первого столбца – id, тип значения – System.Int32.
 c1 = new DataColumn("id", Type.GetType("System.Int32"));
 c1.AutoIncrement=true;
 // Имя второго столбца – Item, тип значения – System.Int32.
 c2 = new DataColumn("Item", Type.GetType("System.Int32"));


 // К таблице добавляются объекты-столбцы...   
 dt.Columns.Add(c1);
 dt.Columns.Add(c2);


 // А вот массив столбцов (здесь он из одного элемента)
 // для организации первичного ключа (множества первичных ключей).
 DataColumn[] keyCol= new DataColumn[1];
 // И вот, собственно, как в таблице задается множество первичных ключей.
 keyCol[0]= c1;
 // Свойству объекта t передается массив, содержащий столбцы, которые
 // формируемая таблица t будет воспринимать как первичные ключи.
 dt.PrimaryKey=keyCol;

 // В таблицу добавляется 10 rows.
 for(int i = 0; i <10;i++)
 {
 	dr=dt.NewRow();
 	dr["Item"]= i;
 	dt.Rows.Add(dr);
 }

 // Принять изменения.
 // Так производится обновление таблицы.
 // Сведения о новых изменениях и добавлениях будут фиксироваться
 // вплоть до нового обновления.
 dt.AcceptChanges();	

 // Здесь мы применим специализированный конструктор, который 
 // задаст значения свойств Table, RowFilter, Sort, RowStateFilter
 // объекта DataView в двух операторах кода...
 //dv = new DataView(dt); // Вместо этого...
 // Определение того, что доступно через объект - представитель DataView.
 // Задавать можно в виде битовой суммы значений. И не все значения сразу!
 // Сумма всех значений – противоречивое сочетание!
 // А можно ли делать это по отдельности?
 DataViewRowState dvrs = DataViewRowState.Added |
 				DataViewRowState.CurrentRows |
 				DataViewRowState.Deleted |
 				DataViewRowState.ModifiedCurrent |

 				//DataViewRowState.ModifiedOriginal |
 				//DataViewRowState.OriginalRows |
 				//DataViewRowState.None |
 // Записи не отображаются.
 DataViewRowState.Unchanged;
 // Вот такое хитрое объявление...
 //  	Таблица,
 //  	|	значение, относительно которого проводится сортировка,
 //  	|   |  
 //  	|   | имя столбца, значения которого сортируются,
 //  	|   |   |                           
 //  	|   |   |  составленное значение DataViewRowState.
 //  	|   |   |      |
 dv = new DataView(dt, "", "Item", dvrs);
 }

 private void buttNext_Click(object sender, System.EventArgs e)
 {
 if (currentCounter+1 < dv.Count) currentCounter++;
 rv = dv[currentCounter];
 demoTextBox.Text = rv["Item"].ToString();
 }


 private void buttPrev_Click(object sender, System.EventArgs e)
 {
 if (currentCounter–1 >= 0) currentCounter––;
 rv = dv[currentCounter];
 demoTextBox.Text = rv["Item"].ToString();
 }

 private void buttFirst_Click(object sender, System.EventArgs e)
 {
 currentCounter = 0;
 rv = dv[currentCounter];
 demoTextBox.Text = rv["Item"].ToString();
 }

 private void buttLast_Click(object sender, System.EventArgs e)
 {
 currentCounter =dv.Count – 1;
 rv = dv[currentCounter];
 demoTextBox.Text = rv["Item"].ToString();
 }

 private void dG_MouseDown
          (object sender, System.Windows.Forms.MouseEventArgs e)
 {
 currentCounter = dG.CurrentRowIndex;
 rv = dv[currentCounter];
 demoTextBox.Text = rv["Item"].ToString();
 }

 // Реализация поиска требует специального опеделения порядка 
 // сортировки строк, который должен задаваться в конструкторе.
 private void buttonFind_Click(object sender, System.EventArgs e)
 {
 int findIndex = –1;

 // Сначала проверяем строку на соответствие формату отыскиваемого 
 // значения.
 // В нашем случае строка должна преобразовываться в целочисленное 
 // значение.
 try
 {
 	int.Parse(findTextBox.Text);	
 }
 catch
 {
 	findTextBox.Text = "Неправильно задан номер...";
 	return;
 }

 findIndex = dv.Find(findTextBox.Text);

 if (findIndex >= 0) 
 {
 	currentCounter = findIndex;
 	rv = dv[currentCounter];
 	demoTextBox.Text = rv["Item"].ToString();
 }
 else
 {
 	findTextBox.Text = "Не нашли.";
 }
 }

 private void buttonAdd_Click(object sender, System.EventArgs e)
 {
 // При создании новой записи средствами вьюера таблицы,
 // связанный с ним вьюер строки переходит в состояние rv.IsNew.
 // При этом в действиях этих объектов есть своя логика.
 // И если туда не вмешиваться, при создании очередной записи
 // предыдущая запись считается принятой и включается в таблицу 
 // автоматически.
 // Контролируя состояния вьюера строки (rv.IsEdit || rv.IsNew),
 // мы можем предотвратить процесс последовательного автоматического
 // обновления таблицы. Все под контролем.
 if (rv.IsEdit || rv.IsNew) return;
 rv = dv.AddNew();
 rv["Item"] = dv.Count–1;			
 }

 private void buttonAcc_Click(object sender, System.EventArgs e)
 {
 // И вот мы вмешались в процесс.
 // Добавление новой записи в таблицу становится возможным лишь
 // после явного завершения редактирования предыдущей записи.
 // Без этого попытки создания новой записи блокируются.
 // Завершить редактирование.
 rv.EndEdit(); 
 // Принять изменения.
 // Так производится обновление таблицы.
 // Сведения о новых изменениях и добавлениях будут фиксироваться
 // вплоть до нового обновления.
 dt.AcceptChanges();	
 }
 }
 }
Листинг 18.6.
< Лекция 17 || Лекция 18: 123456789101112
kewezok kewezok
kewezok kewezok
Елена Шляхт
Елена Шляхт
Объясните плиз в чем отличие а++ от ++а
Почему результат разный?
int a=0, b=0;
Console.WriteLine(a++); //0
Console.WriteLine(++b); //1
a++;
++b;
Console.WriteLine(a); //2
Console.WriteLine(b); //2