Как добавить таблицу в windows form

How do you create a table in winforms where individual cells can look like this: I have been using a tablelayoutpanel, but it only lets you but one control per cell. Any ideas?

There is ALWAYS a way to get it to work. It may not be obvious from the WinForms designer, but it is not too hard.

Try this:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
  partial class Form_1:Form 
  {

    public Form_1()
    {
      InitializeComponent();

    }

    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
      if (disposing && (components != null))
      {
        components.Dispose();
      }
      base.Dispose(disposing);
    }

    private void InitializeComponent()
    {
      this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
      this.panel4 = new System.Windows.Forms.Panel();
      this.panel3 = new System.Windows.Forms.Panel();
      this.panel2 = new System.Windows.Forms.Panel();
      this.panel1 = new System.Windows.Forms.Panel();
      this.tableLayoutPanel1.SuspendLayout();
      this.SuspendLayout();
      // 
      // tableLayoutPanel1
      // 
      this.tableLayoutPanel1.ColumnCount = 2;
      this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
      this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 75F));
      this.tableLayoutPanel1.Controls.Add(this.panel4, 3, 0);
      this.tableLayoutPanel1.Controls.Add(this.panel3, 2, 0);
      this.tableLayoutPanel1.Controls.Add(this.panel2, 1, 0);
      this.tableLayoutPanel1.Controls.Add(this.panel1, 0, 0);
      this.tableLayoutPanel1.SetRowSpan(this.panel1, 3);//This line is the key!!!!!
      this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
      this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
      this.tableLayoutPanel1.Name = "tableLayoutPanel1";
      this.tableLayoutPanel1.RowCount = 3;
      this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
      this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
      this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
      this.tableLayoutPanel1.Size = new System.Drawing.Size(527, 372);
      this.tableLayoutPanel1.TabIndex = 0;
      // 
      // panel4
      // 
      this.panel4.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
      this.panel4.Dock = System.Windows.Forms.DockStyle.Fill;
      this.panel4.Location = new System.Drawing.Point(134, 251);
      this.panel4.Name = "panel4";
      this.panel4.Size = new System.Drawing.Size(390, 118);
      this.panel4.TabIndex = 4;
      // 
      // panel3
      // 
      this.panel3.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
      this.panel3.Dock = System.Windows.Forms.DockStyle.Fill;
      this.panel3.Location = new System.Drawing.Point(134, 127);
      this.panel3.Name = "panel3";
      this.panel3.Size = new System.Drawing.Size(390, 118);
      this.panel3.TabIndex = 3;
      // 
      // panel2
      // 
      this.panel2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
      this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
      this.panel2.Location = new System.Drawing.Point(134, 3);
      this.panel2.Name = "panel2";
      this.panel2.Size = new System.Drawing.Size(390, 118);
      this.panel2.TabIndex = 2;
      // 
      // panel1
      // 
      this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
      this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
      this.panel1.Location = new System.Drawing.Point(3, 3);
      this.panel1.Name = "panel1";
      this.panel1.Size = new System.Drawing.Size(125, 366);
      this.panel1.TabIndex = 1;
      // 
      // Form1
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      this.ClientSize = new System.Drawing.Size(527, 372);
      this.Controls.Add(this.tableLayoutPanel1);
      this.Name = "Form1";
      this.Text = "Form1";
      this.tableLayoutPanel1.ResumeLayout(false);
      this.ResumeLayout(false);

    }

    private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
    private System.Windows.Forms.Panel panel1;
    private System.Windows.Forms.Panel panel3;
    private System.Windows.Forms.Panel panel2;
    private System.Windows.Forms.Panel panel4;
  }
}

The key to get this to work is this line:

this.tableLayoutPanel1.SetRowSpan(this.panel1, 3);//This line is the key!!!!!

Доброго времени суток!

В данной статье я опишу создания своих элементов для C# Windows Form.

Для примера буду создавать таблицу со всем функционалом DataGridView. Позже перейдем на свои элементы. Создание первого элемента разобьем на несколько уроков. В данном уроке произведем от рисовку таблицы, а также: создание столбцов, строк, ячеек.

Для написания будем использовать .Net FrameWork 4.7.x, среда разработки Visual Studio 2019.

В первую очередь создадим обычный проект Windows Form. Думаю не нужно это показывать. А уже потом создаем проект «Библиотека элементов управления Windows Form»(Назовем его CustomControl).

Далее у нас будет создан файл UserControl.cs. Удаляем его и создаем обычный класс TableCustoms.cs.Наш класс будет наследоваться от класса Control.

Далее в этом же файле создадим еще несколько классов, а именно:Column,Row,Cell. Рассмотрим каждый по отдельности. Начнем с Column:

    [Serializable]
    public class Column
    {
        public string Name { get; set; } = "NameColumn";//Наименование Столбца 
        public string Caption { get; set; } = "CaptionColumn";//Текст заголовка
        public int Width { get; set; } = 100;//Стандартная ширина
        public Color Back { get; set; } = Color.White;//Цвет фона
        
        public Column()
        { 
        
        }
    }

Класс Row:

    [Serializable]
    public class Row
    {
        public int Heigth { get; set; } = 20;// Высота строки
        public List<Cell> Cells { get; set; } = new List<Cell>();//список ячеек
        public Row()
        {
 
        }
        public Row(List<Cell> cells)
        {
            Cells = cells;
        }

    }

Класс Cell(Для поддержки копирования добавляем интерфейс ICloneable):

    [Serializable]
    public class Cell : ICloneable
    {
        public object Value { get; set; } = null;//значение ячейки 
        public Cell()
        {
        }
        public object Clone()
        {
            return MemberwiseClone();
        }
    }

Теперь настроим наш основной класс TableCustoms:

   public class TableCustoms : Control
    {
        #region Перемененные
        public ObservableCollection<Column> Columns { get; set; } = new ObservableCollection<Column>();//Список столбцов таблицы
        private ObservableCollection<Row> rows = new ObservableCollection<Row>();//Список строк
        private int countRow = 0;//количество строк
        #endregion
        #region Свойства
        public int CountRow // гетер и сетер при увеличении переменной на N раз
        {
            get { return countRow; }
            set
            {
                //При увеличении добавляем 
                if (value > countRow)
                {
                    int iteration = value - countRow;
                    for (int i = 0; i < iteration; i++)
                    {
                        rows.Add(new Row());
                    }
                }
                //при уменьшении удаляем с конца
                if (value < countRow)
                {
                    int iteration = countRow - value;
                    for (int i = 0; i < iteration; i++)
                    {
                        rows.Remove(rows[rows.Count - 1]);
                    }
                }

                countRow = value;
            }
        }
        //гетер и сетер для списка строк, будет использоваться позже
        public ObservableCollection<Row> Rows
        {
            get { return rows; }
            set { }
        }

        public int ColumnHeaderHeigth { get; set; } = 20;//высота шапки таблицы
        public int RowHeaderWidth { get; set; } = 20;//высота заголовков строк
        public Color ColumnHeaderBack { get; set; } = SystemColors.Control;//Основной цвет фона заголовков таблицы
        public Color BorderColor { get; set; } = Color.Black;//Стандартный цвет границ таблицы
        public bool NumerableRows { get; set; } = false;//Флаг автоматической нумерации
        #endregion
        //Метода изменения столбцов, будет использоваться в следующем уроке
        private void EditColumn()
        {

        }
        //Метод изменения строк
        private void EditRows()
        {
            if (countRow < rows.Count)//Увеличение количества строк
            {
                rows[rows.Count - 1].Cells = CreatCells(Columns.Count);//Добавление пустых ячеек в строку
                countRow++;
            }
            if (CountRow > rows.Count)//уменьшение количества строк
            {
                countRow--;
            }

        }
        //метод создания N количества ячеек
        private List<Cell> CreatCells(int Count)
        {
            // return Enumerable.Repeat(new Cell(), Count).ToList();
            List<Cell> result = new List<Cell>();
            for (int i = 0; i < Count; i++)
            {
                result.Add(new Cell());
            }
            return result;
        }
        public TableCustoms()
        {
            rows.CollectionChanged += (e, v) => EditRows();//проверка изменения списка
            Columns.CollectionChanged += (e, v) => EditColumn();//проверка изменения списка
            BackColor = SystemColors.AppWorkspace;//Стандартный фон
            PanelTable panelTable = new PanelTable(this);//Создание основной панели
            panelTable.Dock = DockStyle.Fill;//Растягиваем основную панель по Control
            Controls.Add(panelTable);//Добавление панели на Control
        }
    }

Для того, чтобы у нас были полосы прокрутки нужно использовать ScrollableControl, поэтому создадим класс PanelTable наследуем ScrollableControl и помещаем его на Control(в следующем уроке объясню почему создаем два разных контрола, а не используем сразу ScrollableControl):

 internal class PanelTable : ScrollableControl//Control со ScrolLbar
        {
            private TableCustoms BParent;//переменная основного класса, для работы с свойствами
            public PanelTable(TableCustoms bParent)
            {
                HScroll = true;//Отображение ползунка по горизонтали
                VScroll = true;//Отображение ползунка по вертикали
                AutoScroll = true;//Автоматическое появление полос прокрутки
                BParent = bParent;
            }
            //переопределение метода
            protected override void OnPaint(PaintEventArgs e)
            {
                Matrix m = new Matrix();
                m.Translate(this.AutoScrollPosition.X, this.AutoScrollPosition.Y, MatrixOrder.Append);
                e.Graphics.Transform = m;
                Graphics graf = e.Graphics;
                int maxWidth = 0;//Высота AutoScrollMinSize
                int maxHeight = 0;//Ширина AutoScrollMinSize
                                  //расчитываем ширину
                foreach (Column item in BParent.Columns)
                {
                    maxWidth += item.Width;
                }
                //расчитываем высоту
                foreach (Row item in BParent.Rows)
                {
                    maxHeight += item.Heigth;
                }
                AutoScrollMinSize = new Size(maxWidth + 100, maxHeight + 100);//назначаем AutoScrollMinSize относительно этого будут появляться полосы прокрутки
                graf.Clear(BParent.BackColor);
                DrawHeaderColumns(graf);//Отрисовка заголовков столбцов таблицы
                DrawHeaderRows(graf);//Отрисовка заголовков строк таблицы
                DrawCells(graf);//Отрисовка ячеек
                base.OnPaint(e);
            }
            /// <summary>
            /// Отрисока заголовков столбцов
            /// </summary>
            /// <param name="graf"></param>
            private void DrawHeaderColumns(Graphics graf)
            {
                int x = 2;
                Rectangle rect;
                rect = new Rectangle(x, 1, BParent.RowHeaderWidth, BParent.ColumnHeaderHeigth);
                graf.DrawRectangle(new Pen(BParent.BorderColor), rect);
                graf.FillRectangle(new SolidBrush(BParent.ColumnHeaderBack), rect);
                x += BParent.RowHeaderWidth + 1;
                foreach (Column item in BParent.Columns)
                {
                    rect = new Rectangle(x, 1, item.Width, BParent.ColumnHeaderHeigth);
                    graf.DrawRectangle(new Pen(BParent.BorderColor), rect);
                    graf.FillRectangle(new SolidBrush(BParent.ColumnHeaderBack), rect);
                    if (item.Caption.Length != 0)
                    {
                        StringFormat sf = new StringFormat();
                        sf.Alignment = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Center;
                        graf.DrawString(item.Caption, new Font("Times", 9), Brushes.Black, rect, sf);
                    }
                    x += item.Width + 1;
                }
            }
            //Отрисовка заголовков строк
            private void DrawHeaderRows(Graphics graf)
            {
                int y = 1;
                int i = 0;
                Rectangle rect;
                y += BParent.RowHeaderWidth + 1;
                foreach (Row item in BParent.Rows)
                {
                    rect = new Rectangle(2, y, BParent.RowHeaderWidth, item.Heigth);
                    graf.DrawRectangle(new Pen(BParent.BorderColor), rect);
                    graf.FillRectangle(new SolidBrush(BParent.ColumnHeaderBack), rect);
                    if (BParent.NumerableRows)
                    {
                        StringFormat sf = new StringFormat();
                        sf.Alignment = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Center;
                        graf.DrawString(i.ToString(), new Font("Times", 9), Brushes.Black, rect, sf);
                    }
                    i++;
                    y += item.Heigth + 1;
                }
            }
            //отрисовка ячеек
            private void DrawCells(Graphics graf)
            {

                int x = 2 + BParent.RowHeaderWidth + 1;
                int y = 2 + BParent.ColumnHeaderHeigth;
                Rectangle rect;
                int i = 0;
                foreach (Row itemRow in BParent.Rows)
                {
                    foreach (Column itemColumn in BParent.Columns)
                    {
                        rect = new Rectangle(x, y, itemColumn.Width, itemRow.Heigth);
                        graf.DrawRectangle(new Pen(BParent.BorderColor), rect);
                        graf.FillRectangle(new SolidBrush(Color.White), rect);
                        if (itemRow.Cells[i].Value != null)
                        {
                            StringFormat sf = new StringFormat();
                            sf.Alignment = StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Center;
                            graf.DrawString(itemRow.Cells[i].Value.ToString(), new Font("Times", 9), Brushes.Black, rect, sf);
                        }
                        x += itemColumn.Width + 1;
                        i++;
                    }
                    i = 0;
                    y += itemRow.Heigth + 1;
                    x = 2 + BParent.RowHeaderWidth + 1;
                }
            }
        }

После этого «Пересобираем проект» элемента и добавляем элемент на форму(в основном проекте):

image

Теперь проверим некоторые методы нашего элемента:

  public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
             tableCustoms1.Rows.Add(new Row());//добавление строки
             tableCustoms1.Rows.Add(new Row());
             tableCustoms1.Rows[0].Cells[0].Value = "1";//Изменение значения ячейки
             tableCustoms1.Rows[1].Cells[1].Value = "2";
            tableCustoms1.CountRow++;//увеличение числа строк
            tableCustoms1.Rows[0].Cells[0].Value = "привет";
        }
    }

Запускаем наш проект:

image

Последнее обновление: 31.10.2015

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

Чтобы установить нужное число строки столбцов таблицы, мы можем использовать свойства Rows и Columns соответственно. Выбрав один из этих пунктов в
окне Properties (Свойства), нам отобразится следующее окно для настройки столбцов и строк:

Настройка столбцов и строк элемента TableLayoutPanel

В поле Size Type мы можем указать размер столбцов / строк. Нам доступны три возможные варианта:

  • Absolute: задается абсолютный размер для строк или столбцов в пикселях

  • Percent: задается относительный размер в процентах. Если нам надо создать резиновый дизайн формы, чтобы ее строки и столбцы, а также
    элементы управления в ячейках таблицы автоматически масштабировались при изменении размеров формы, то нам нужно использовать именно эту опцию

  • AutoSize: высота строк и ширина столбцов задается автоматически в зависимости от размера самой большой в строке
    или столбце ячейки

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

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

Итак, например, у меня имеется три столбца и три строки размер у которых одинаков — 33.33%. В каждую ячейку таблицы добавлена кнопка, у которой установлено свойство
Dock=Fill.

Если я изменю размеры формы, то автоматически масштабируются и строки и столбцы вместе с заключенными в них кнопками:

TableLayoutPanel в Windows Forms

Что довольно удобно для создания масштабируемых интерфейсов.

В коде динамически мы можем изменять значения столбцов и строк. Причем все столбцы представлены типом ColumnStyle,
а строки — типом RowStyle:

tableLayoutPanel1.RowStyles[0].SizeType = SizeType.Percent;
tableLayoutPanel1.RowStyles[0].Height = 40;

tableLayoutPanel1.ColumnStyles[0].SizeType = SizeType.Absolute;
tableLayoutPanel1.ColumnStyles[0].Width = 50;

Для установки размера в ColumnStyle и RowStyle определено свойство SizeType, которое принимает одно из значений одноименного перечисления
SizeType

Добавление элемента в контейнер TableLayoutPanel имеет свои особенности. Мы можем добавить его как в следующую свободную ячейку или можем явным
образом указать ячейку таблицы:

Button saveButton = new Button();
// добавляем кнопку в следующую свободную ячейку
tableLayoutPanel1.Controls.Add(saveButton);
// добавляем кнопку в ячейку (2,2)
tableLayoutPanel1.Controls.Add(saveButton, 2, 2);

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

Создание собственного элемента на примере таблицы на C# для Windows Form

В данной статье я опишу создания своих элементов для C# Windows Form.

Для примера буду создавать таблицу со всем функционалом DataGridView. Позже перейдем на свои элементы. Создание первого элемента разобьем на несколько уроков. В данном уроке произведем от рисовку таблицы, а также: создание столбцов, строк, ячеек.

Для написания будем использовать .Net FrameWork 4.7.x, среда разработки Visual Studio 2019.

В первую очередь создадим обычный проект Windows Form. Думаю не нужно это показывать. А уже потом создаем проект «Библиотека элементов управления Windows Form»(Назовем его CustomControl).

Далее у нас будет создан файл UserControl.cs. Удаляем его и создаем обычный класс TableCustoms.cs.Наш класс будет наследоваться от класса Control.

Далее в этом же файле создадим еще несколько классов, а именно:Column,Row,Cell. Рассмотрим каждый по отдельности. Начнем с Column:

Класс Cell(Для поддержки копирования добавляем интерфейс ICloneable):

Теперь настроим наш основной класс TableCustoms:

Для того, чтобы у нас были полосы прокрутки нужно использовать ScrollableControl, поэтому создадим класс PanelTable наследуем ScrollableControl и помещаем его на Control(в следующем уроке объясню почему создаем два разных контрола, а не используем сразу ScrollableControl):

После этого «Пересобираем проект» элемента и добавляем элемент на форму(в основном проекте):

Пошаговое руководство. Создание dataTable в конструкторе наборов данных

В этом пошаговом руководстве объясняется, как создать DataTable (без TableAdapter) с помощью конструктора наборов данных. Сведения о создании таблиц данных, включая TableAdapters, см. в разделе «Создание и настройка TableAdapters».

Создание приложения Windows Forms

В Visual Studio в меню Файл выберите пункты Создать>Проект.

Разверните visual C# или Visual Basic на панели слева, а затем выберите «Рабочий стол Windows«.

В средней области выберите тип проекта приложения Windows Forms .

Назовите проект DataTableWalkthrough и нажмите кнопку «ОК«.

Проект DataTableWalkthrough создается и добавляется в обозреватель решений.

Добавление нового набора данных в приложение

В меню Проект выберите команду Добавить новый элемент.

Откроется диалоговое окно Добавление нового элемента.

На панели слева выберите «Данные«, а затем выберите DataSet в средней области.

Выберите Добавить.

Visual Studio добавляет в проект файл с именем DataSet1.xsd и открывает его в конструкторе наборов данных.

Добавление новой dataTable в набор данных

Перетащите dataTable с вкладки DataSetпанели элементов в конструктор наборов данных.

Таблица с именем DataTable1 добавляется в набор данных.

Щелкните заголовок строки DataTable1 и переименуйте ее Music .

Добавление столбцов в Таблицу данных

Щелкните правой кнопкой мыши таблицу «Музыка «. Наведите указатель на пункт «Добавить» и нажмите кнопку «Столбец«.

Присвойт столбцу SongID имя.

В окне Свойства присвойте свойству DataType значение System.Int16.

Повторите этот процесс и добавьте следующие столбцы:

Установка первичного ключа для таблицы

Все таблицы данных должны иметь первичный ключ. Первичный ключ однозначно идентифицирует определенную запись в таблице данных.

Чтобы задать первичный ключ, щелкните правой кнопкой мыши столбец SongID и выберите команду «Задать первичный ключ«. Рядом со столбцом SongID появится значок клавиши.

Сохранение проекта

Чтобы сохранить проект DataTableWalkthrough , в меню «Файл » выберите «Сохранить все«.

Создать Excel в visual studio c#

Давайте научимся быстро и просто создавать и записывать файлы Excel с помощью visual studio c#. Наше самое простое приложение Windows Forms будет брать из текстбокса текст и заносить его в первую ячейку. Статья написана специально для Сергея =).

Начать необходимо с подключения библиотеки Microsoft.Office.Interop.Excel. Выглядеть это должно так:

Если у вас при открытии обозревателя решений – Ссылки – правая кнопка – Добавить ссылку – Сборки – в списке нет Microsoft.Office.Interop.Excel, то добавьте её через Nuget. Проект – управление пакетами NuGet – в строке поиска Excel:

Теперь создайте новый проект Windows Forms и на форму закиньте текстбокс и кнопку. На кнопки кликните два раза, откроется исходный код. В самом верху допишите следующее:

А в методе button1_Click замените так:

Вот, собственно говоря и все. Текст из текстбокса запишется в ячейку A1. Обратите внимание, что папка temp на диске уже должна существовать.

Дополнение. Прочитать первую ячейку

Это тоже просто:


Автор этого материала — я — Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML — то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, си шарп, excel

создание и заполнение таблицы программно

заполнение таблицы динамически

запись и мгновенное отображение данных

заполнение dataGridView из текстового файла

запись из dataGridView в текстовый файл

создание и заполнение таблицы программно

Скрыть

Показать

Копировать

  Form1.cs  

  • using System;
  • using System.Collections.Generic;
  • using System.ComponentModel;
  • using System.Data;
  • using System.Drawing;
  • using System.Linq;
  • using System.Text;
  • using System.Threading.Tasks;
  • using System.Windows.Forms;
  •  
  • namespace _0070 {
  •  public partial class Form1 : Form {
  •   
  •   DataGridView dataGridView1 = new DataGridView();
  •   void Funtcion() {
  •    
  •    dataGridView1.Size = new Size(400, 200);
  •  
  •    
  •    
  •    DataGridViewTextBoxColumn column0 = new DataGridViewTextBoxColumn();
  •    column0.Name = "id";
  •    column0.HeaderText = "ID";
  •    
  •    DataGridViewTextBoxColumn column1 = new DataGridViewTextBoxColumn();
  •    column1.Name = "brand";
  •    column1.HeaderText = "Brand";
  •    
  •    DataGridViewImageColumn column2 = new DataGridViewImageColumn();
  •    column2.Name = "image";
  •    column2.HeaderText = "Image";
  •    
  •    dataGridView1.Columns.AddRange(column0, column1, column2);
  •  
  •    
  •    
  •    DataGridViewCell id0 = new DataGridViewTextBoxCell();
  •    DataGridViewCell brand0 = new DataGridViewTextBoxCell();
  •    DataGridViewCell image0 = new DataGridViewImageCell();
  •    id0.Value = "1";
  •    brand0.Value = "BMW";
  •    image0.Value = imageList1.Images[0];
  •    
  •    DataGridViewRow row0 = new DataGridViewRow();
  •    
  •    row0.Cells.AddRange(id0, brand0, image0);
  •    
  •    dataGridView1.Rows.Add(row0);
  •  
  •    
  •    DataGridViewCell id1 = new DataGridViewTextBoxCell();
  •    DataGridViewCell brand1 = new DataGridViewTextBoxCell();
  •    DataGridViewCell image1 = new DataGridViewImageCell();
  •    id1.Value = "2";
  •    brand1.Value = "Bentley";
  •    image1.Value = imageList1.Images[1];
  •    
  •    DataGridViewRow row1 = new DataGridViewRow();
  •    
  •    row1.Cells.AddRange(id1, brand1, image1);
  •    
  •    dataGridView1.Rows.Add(row1);
  •  
  •    
  •    DataGridViewCell id2 = new DataGridViewTextBoxCell();
  •    DataGridViewCell brand2 = new DataGridViewTextBoxCell();
  •    DataGridViewCell image2 = new DataGridViewImageCell();
  •    id2.Value = "3";
  •    brand2.Value = "Mercedes";
  •    image2.Value = imageList1.Images[2];
  •    
  •    DataGridViewRow row2 = new DataGridViewRow();
  •    
  •    row2.Cells.AddRange(id2, brand2, image2);
  •    
  •    dataGridView1.Rows.Add(row2);
  •   }
  •   public Form1() {
  •    InitializeComponent();
  •    
  •    this.Controls.Add(dataGridView1);
  •    Funtcion();
  •   }
  •  }
  • }

заполнение таблицы динамически

Скрыть

Показать

Копировать

  Form1.cs  

  • using System;
  • using System.Collections.Generic;
  • using System.ComponentModel;
  • using System.Data;
  • using System.Drawing;
  • using System.Linq;
  • using System.Text;
  • using System.Threading.Tasks;
  • using System.Windows.Forms;
  •  
  • namespace _0071 {
  •  public partial class Form1 : Form {
  •   int counter = 0;
  •   public Form1() {
  •    InitializeComponent();
  •   }
  •   
  •   private void buttonBrowse_Click(object sender, EventArgs e) {
  •    openFileDialog1.Filter = "Images (*.jpg; *.jpeg; *.gif; *.bmp; *.ico; *.png) | *.jpg; *.jpeg; *.gif; *.bmp; *.ico; *.png";
  •    if(openFileDialog1.ShowDialog() == DialogResult.OK) {
  •     imageList1.Images.Add(Image.FromFile(openFileDialog1.FileName));
  •    }
  •   }
  •   
  •   private void buttonAdd_Click(object sender, EventArgs e) {
  •    
  •    DataGridViewCell brand = new DataGridViewTextBoxCell();
  •    DataGridViewCell image = new DataGridViewImageCell();
  •    
  •    brand.Value = textBoxBrend.Text;
  •    image.Value = imageList1.Images[counter++];
  •    
  •    DataGridViewRow row = new DataGridViewRow();
  •    
  •    row.Cells.AddRange(brand, image);
  •    
  •    dataGridView1.Rows.Add(row);
  •  
  •    textBoxBrend.Clear();
  •    
  •    dataGridView1.Refresh();
  •    textBoxBrend.Select();
  •   }
  •   
  •   private void buttonClear_Click(object sender, EventArgs e) {
  •    dataGridView1.Rows.Clear();
  •   }
  •  }
  • }

запись и мгновенное отображение данных

Создайте базу данных «abc» и таблицу «Avto».

Скрыть

Показать

Копировать

  *.sql  

CREATE DATABASE abc
GO
USE abc
GO
CREATE TABLE [dbo].[Avto] (
 [Id]           INT             IDENTITY (1, 1) NOT NULL,
 [Brand]        VARCHAR (255)   NOT NULL,
 [ImageBrand]   VARBINARY (MAX) NOT NULL,
 [Country]      VARCHAR (255)   NOT NULL,
 [ImageCountry] IMAGE           NOT NULL,
 CONSTRAINT [PK_Avto] PRIMARY KEY CLUSTERED ([Id] ASC)
);

Скрыть

Показать

Копировать

  Form1.cs  

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
using System.Data.SqlClient;
using System.IO;
 
namespace _0072 {
 public partial class Form1 : Form {
  string pathImageBrand = string.Empty;
  string pathImageCountry = string.Empty;
  public Form1() {
   InitializeComponent();
  }
  //кнопка Brand / Browse 
  private void buttonBrowseBrand_Click(object sender, EventArgs e) {
   openFileDialog1.Filter = "Images (*.jpg; *.jpeg; *.gif; *.bmp; *.ico; *.png) | *.jpg; *.jpeg; *.gif; *.bmp; *.ico; *.png";
   if(openFileDialog1.ShowDialog() == DialogResult.OK) {
    pathImageBrand = openFileDialog1.FileName.ToString();
   }
  }
  //кнопка Country / Browse
  private void buttonBrowseCountry_Click(object sender, EventArgs e) {
   openFileDialog2.Filter = "Images (*.jpg; *.jpeg; *.gif; *.bmp; *.ico; *.png) | *.jpg; *.jpeg; *.gif; *.bmp; *.ico; *.png";
   if(openFileDialog2.ShowDialog() == DialogResult.OK) {
    pathImageCountry = openFileDialog2.FileName.ToString();
   }
  }
  //кнопка Add
  private void buttonAdd_Click(object sender, EventArgs e) {
   string stringConnect = @"Data Source=BISEMMSSQLSERVER2012;Initial Catalog=abc;Integrated Security=True";
   string sql = "INSERT INTO Avto VALUES("+null+" '"+textBoxBrand.Text+"', @imgBrands, '"+textBoxCountry.Text+"', @imgCountries)";
 
   byte[] imgBrands = null;
   FileStream fsBrand = new FileStream(pathImageBrand, FileMode.Open, FileAccess.Read);
   BinaryReader brBrand = new BinaryReader(fsBrand);
   imgBrands = brBrand.ReadBytes((int)fsBrand.Length);
 
   byte[] imgCountries = null;
   FileStream fsCountry = new FileStream(pathImageCountry, FileMode.Open, FileAccess.Read);
   BinaryReader brCountry = new BinaryReader(fsCountry);
   imgCountries = brCountry.ReadBytes((int)fsCountry.Length);
 
   using(SqlConnection connect = new SqlConnection(stringConnect)) {
    try {
     connect.Open();
     SqlCommand command = new SqlCommand(sql, connect);
     command.Parameters.Add(new SqlParameter("@imgBrands", imgBrands));
     command.Parameters.Add(new SqlParameter("@imgCountries", imgCountries));
     int x = command.ExecuteNonQuery();
     MessageBox.Show(x.ToString() + " Record added");
    }
    catch(Exception exc) {
     MessageBox.Show("Error connection with a database {0}", exc.Message);
    }
   }
 
   textBoxBrand.Clear();
   textBoxCountry.Clear();
   this.avtoTableAdapter.Fill(this.abcDataSet.Avto);
   textBoxBrand.Select();
  }
 
  private void Form1_Load(object sender, EventArgs e) {
   // TODO: This line of code loads data into the 'abcDataSet.Avto' table. You can move, or remove it, as needed.
   this.avtoTableAdapter.Fill(this.abcDataSet.Avto);
  }
 }
}

База данных находится в папке «database» в архиве.

заполнение dataGridView из текстового файла

Скрыть

Показать

Копировать

  Form1.cs  

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
using System.IO;
 
namespace _0073 {
 public partial class Form1 : Form {
  //метод заполняет dataGridView данными из текстового файла
  public void Function() {
   DataSet ds = new DataSet();
   //создаем временную таблицу
   ds.Tables.Add("Temp");
 
   //путь к текстовому файлу
   string path = @"a.txt";
   StreamReader sr = new StreamReader(path);
 
   /*создаем колонки в таблице и заполняем их названиями*/
   //считываем первую строку из файла, в ней названия столбцов
   string firstLine = sr.ReadLine();
   //массив имен колонок из файла
   string[] arraNameColumn = System.Text.RegularExpressions.Regex.Split(firstLine, ",");
   for(int i=0; i<arraNameColumn.Length; i++) {
    ds.Tables[0].Columns.Add(arraNameColumn[i]);
   }
 
   /*заполняем строки в таблице*/
   string Line = sr.ReadLine();
   while(Line != null) {
    string[] arraCell = System.Text.RegularExpressions.Regex.Split(Line, ",");
    ds.Tables[0].Rows.Add(arraCell);
    Line = sr.ReadLine();
   }
 
   //привязываем dataGridView к таблице
   dataGridView1.DataSource = ds.Tables[0];
  }
  public Form1() {
   InitializeComponent();
   Function();
  }
 }
}

запись из dataGridView в текстовый файл

Скрыть

Показать

Копировать

  Form1.cs  

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
using System.IO;
 
namespace _0074 {
 public partial class Form1 : Form {
  string path = string.Empty;
  public Form1() {
   InitializeComponent();
  }
  //кнопка Browse file
  private void button1_Click(object sender, EventArgs e) {
   openFileDialog1.Filter = "Text (*.txt) | *.txt";
   if(openFileDialog1.ShowDialog() == DialogResult.OK) { 
    path = openFileDialog1.FileName;
   }
  }
  //кнопка Record into file
  private void button2_Click(object sender, EventArgs e) {
   using(StreamWriter sw = new StreamWriter(path, true)) {
    for(int i = 0; i < Convert.ToInt32(dataGridView1.Rows.Count-1); i++) {
     sw.WriteLine(dataGridView1.Rows[i].Cells[0].Value.ToString() + "t" + dataGridView1.Rows[i].Cells[1].Value.ToString());
    }
   }
  }
 }
}

Доброго времени суток!

В данной статье я опишу создания своих элементов для C# Windows Form.

Для примера буду создавать таблицу со всем функционалом DataGridView. Позже перейдем на свои элементы. Создание первого элемента разобьем на несколько уроков. В данном уроке произведем от рисовку таблицы, а также: создание столбцов, строк, ячеек.

Для написания будем использовать .Net FrameWork 4.7.x, среда разработки Visual Studio 2019.

В первую очередь создадим обычный проект Windows Form. Думаю не нужно это показывать. А уже потом создаем проект «Библиотека элементов управления Windows Form»(Назовем его CustomControl).

Далее у нас будет создан файл UserControl.cs. Удаляем его и создаем обычный класс TableCustoms.cs.Наш класс будет наследоваться от класса Control.

Далее в этом же файле создадим еще несколько классов, а именно:Column,Row,Cell. Рассмотрим каждый по отдельности. Начнем с Column:

    [Serializable]
    public class Column
    {
        public string Name { get; set; } = "NameColumn";//Наименование Столбца 
        public string Caption { get; set; } = "CaptionColumn";//Текст заголовка
        public int Width { get; set; } = 100;//Стандартная ширина
        public Color Back { get; set; } = Color.White;//Цвет фона
        
        public Column()
        { 
        
        }
    }

Класс Row:

    [Serializable]
    public class Row
    {
        public int Heigth { get; set; } = 20;// Высота строки
        public List<Cell> Cells { get; set; } = new List<Cell>();//список ячеек
        public Row()
        {
 
        }
        public Row(List<Cell> cells)
        {
            Cells = cells;
        }

    }

Класс Cell(Для поддержки копирования добавляем интерфейс ICloneable):

    [Serializable]
    public class Cell : ICloneable
    {
        public object Value { get; set; } = null;//значение ячейки 
        public Cell()
        {
        }
        public object Clone()
        {
            return MemberwiseClone();
        }
    }

Теперь настроим наш основной класс TableCustoms:

   public class TableCustoms : Control
    {
        #region Перемененные
        public ObservableCollection<Column> Columns { get; set; } = new ObservableCollection<Column>();//Список столбцов таблицы
        private ObservableCollection<Row> rows = new ObservableCollection<Row>();//Список строк
        private int countRow = 0;//количество строк
        #endregion
        #region Свойства
        public int CountRow // гетер и сетер при увеличении переменной на N раз
        {
            get { return countRow; }
            set
            {
                //При увеличении добавляем 
                if (value > countRow)
                {
                    int iteration = value - countRow;
                    for (int i = 0; i < iteration; i++)
                    {
                        rows.Add(new Row());
                    }
                }
                //при уменьшении удаляем с конца
                if (value < countRow)
                {
                    int iteration = countRow - value;
                    for (int i = 0; i < iteration; i++)
                    {
                        rows.Remove(rows[rows.Count - 1]);
                    }
                }

                countRow = value;
            }
        }
        //гетер и сетер для списка строк, будет использоваться позже
        public ObservableCollection<Row> Rows
        {
            get { return rows; }
            set { }
        }

        public int ColumnHeaderHeigth { get; set; } = 20;//высота шапки таблицы
        public int RowHeaderWidth { get; set; } = 20;//высота заголовков строк
        public Color ColumnHeaderBack { get; set; } = SystemColors.Control;//Основной цвет фона заголовков таблицы
        public Color BorderColor { get; set; } = Color.Black;//Стандартный цвет границ таблицы
        public bool NumerableRows { get; set; } = false;//Флаг автоматической нумерации
        #endregion
        //Метода изменения столбцов, будет использоваться в следующем уроке
        private void EditColumn()
        {

        }
        //Метод изменения строк
        private void EditRows()
        {
            if (countRow < rows.Count)//Увеличение количества строк
            {
                rows[rows.Count - 1].Cells = CreatCells(Columns.Count);//Добавление пустых ячеек в строку
                countRow++;
            }
            if (CountRow > rows.Count)//уменьшение количества строк
            {
                countRow--;
            }

        }
        //метод создания N количества ячеек
        private List<Cell> CreatCells(int Count)
        {
            // return Enumerable.Repeat(new Cell(), Count).ToList();
            List<Cell> result = new List<Cell>();
            for (int i = 0; i < Count; i++)
            {
                result.Add(new Cell());
            }
            return result;
        }
        public TableCustoms()
        {
            rows.CollectionChanged += (e, v) => EditRows();//проверка изменения списка
            Columns.CollectionChanged += (e, v) => EditColumn();//проверка изменения списка
            BackColor = SystemColors.AppWorkspace;//Стандартный фон
            PanelTable panelTable = new PanelTable(this);//Создание основной панели
            panelTable.Dock = DockStyle.Fill;//Растягиваем основную панель по Control
            Controls.Add(panelTable);//Добавление панели на Control
        }
    }

Для того, чтобы у нас были полосы прокрутки нужно использовать ScrollableControl, поэтому создадим класс PanelTable наследуем ScrollableControl и помещаем его на Control(в следующем уроке объясню почему создаем два разных контрола, а не используем сразу ScrollableControl):

 internal class PanelTable : ScrollableControl//Control со ScrolLbar
        {
            private TableCustoms BParent;//переменная основного класса, для работы с свойствами
            public PanelTable(TableCustoms bParent)
            {
                HScroll = true;//Отображение ползунка по горизонтали
                VScroll = true;//Отображение ползунка по вертикали
                AutoScroll = true;//Автоматическое появление полос прокрутки
                BParent = bParent;
            }
            //переопределение метода
            protected override void OnPaint(PaintEventArgs e)
            {
                Matrix m = new Matrix();
                m.Translate(this.AutoScrollPosition.X, this.AutoScrollPosition.Y, MatrixOrder.Append);
                e.Graphics.Transform = m;
                Graphics graf = e.Graphics;
                int maxWidth = 0;//Высота AutoScrollMinSize
                int maxHeight = 0;//Ширина AutoScrollMinSize
                                  //расчитываем ширину
                foreach (Column item in BParent.Columns)
                {
                    maxWidth += item.Width;
                }
                //расчитываем высоту
                foreach (Row item in BParent.Rows)
                {
                    maxHeight += item.Heigth;
                }
                AutoScrollMinSize = new Size(maxWidth + 100, maxHeight + 100);//назначаем AutoScrollMinSize относительно этого будут появляться полосы прокрутки
                graf.Clear(BParent.BackColor);
                DrawHeaderColumns(graf);//Отрисовка заголовков столбцов таблицы
                DrawHeaderRows(graf);//Отрисовка заголовков строк таблицы
                DrawCells(graf);//Отрисовка ячеек
                base.OnPaint(e);
            }
            /// <summary>
            /// Отрисока заголовков столбцов
            /// </summary>
            /// <param name="graf"></param>
            private void DrawHeaderColumns(Graphics graf)
            {
                int x = 2;
                Rectangle rect;
                rect = new Rectangle(x, 1, BParent.RowHeaderWidth, BParent.ColumnHeaderHeigth);
                graf.DrawRectangle(new Pen(BParent.BorderColor), rect);
                graf.FillRectangle(new SolidBrush(BParent.ColumnHeaderBack), rect);
                x += BParent.RowHeaderWidth + 1;
                foreach (Column item in BParent.Columns)
                {
                    rect = new Rectangle(x, 1, item.Width, BParent.ColumnHeaderHeigth);
                    graf.DrawRectangle(new Pen(BParent.BorderColor), rect);
                    graf.FillRectangle(new SolidBrush(BParent.ColumnHeaderBack), rect);
                    if (item.Caption.Length != 0)
                    {
                        StringFormat sf = new StringFormat();
                        sf.Alignment = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Center;
                        graf.DrawString(item.Caption, new Font("Times", 9), Brushes.Black, rect, sf);
                    }
                    x += item.Width + 1;
                }
            }
            //Отрисовка заголовков строк
            private void DrawHeaderRows(Graphics graf)
            {
                int y = 1;
                int i = 0;
                Rectangle rect;
                y += BParent.RowHeaderWidth + 1;
                foreach (Row item in BParent.Rows)
                {
                    rect = new Rectangle(2, y, BParent.RowHeaderWidth, item.Heigth);
                    graf.DrawRectangle(new Pen(BParent.BorderColor), rect);
                    graf.FillRectangle(new SolidBrush(BParent.ColumnHeaderBack), rect);
                    if (BParent.NumerableRows)
                    {
                        StringFormat sf = new StringFormat();
                        sf.Alignment = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Center;
                        graf.DrawString(i.ToString(), new Font("Times", 9), Brushes.Black, rect, sf);
                    }
                    i++;
                    y += item.Heigth + 1;
                }
            }
            //отрисовка ячеек
            private void DrawCells(Graphics graf)
            {

                int x = 2 + BParent.RowHeaderWidth + 1;
                int y = 2 + BParent.ColumnHeaderHeigth;
                Rectangle rect;
                int i = 0;
                foreach (Row itemRow in BParent.Rows)
                {
                    foreach (Column itemColumn in BParent.Columns)
                    {
                        rect = new Rectangle(x, y, itemColumn.Width, itemRow.Heigth);
                        graf.DrawRectangle(new Pen(BParent.BorderColor), rect);
                        graf.FillRectangle(new SolidBrush(Color.White), rect);
                        if (itemRow.Cells[i].Value != null)
                        {
                            StringFormat sf = new StringFormat();
                            sf.Alignment = StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Center;
                            graf.DrawString(itemRow.Cells[i].Value.ToString(), new Font("Times", 9), Brushes.Black, rect, sf);
                        }
                        x += itemColumn.Width + 1;
                        i++;
                    }
                    i = 0;
                    y += itemRow.Heigth + 1;
                    x = 2 + BParent.RowHeaderWidth + 1;
                }
            }
        }

После этого «Пересобираем проект» элемента и добавляем элемент на форму(в основном проекте):

image

Теперь проверим некоторые методы нашего элемента:

  public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
             tableCustoms1.Rows.Add(new Row());//добавление строки
             tableCustoms1.Rows.Add(new Row());
             tableCustoms1.Rows[0].Cells[0].Value = "1";//Изменение значения ячейки
             tableCustoms1.Rows[1].Cells[1].Value = "2";
            tableCustoms1.CountRow++;//увеличение числа строк
            tableCustoms1.Rows[0].Cells[0].Value = "привет";
        }
    }

Запускаем наш проект:

image

Автор: Сидоров Артем Алексеевич

Источник

3 / 3 / 1

Регистрация: 16.04.2009

Сообщений: 127

1

03.05.2009, 17:14. Показов 41623. Ответов 11


Здравствуйте!

Мне нужно в приложении Windows Forms представить результат работы программы в виде небольшой табличке, содержащей 2 столбца целых цифр. (строк порядка 10-20).

Это табличка должна располагаться прямо на форме.

Подскажите, как это лучше сделать?

Я думаю что можно сделать многострочный элемент TextBox. Или есть более эффективные способы?

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



1507 / 774 / 103

Регистрация: 22.04.2008

Сообщений: 1,610

03.05.2009, 18:00

2

я вот думаю лучше через компонент DataGridView.

Добавлено через 57 секунд
Он как раз служить для представления данных в табличном виде.



1



3 / 3 / 1

Регистрация: 16.04.2009

Сообщений: 127

03.05.2009, 18:52

 [ТС]

3

А у вас нет примеров работы с этом компонентом? а то я чувствую что сам не разберусь…



0



1507 / 774 / 103

Регистрация: 22.04.2008

Сообщений: 1,610

03.05.2009, 19:15

4

Помогу конечно

Добавлено через 11 минут 53 секунды
У вас результат представляется в каком виде матрица или как?



0



3 / 3 / 1

Регистрация: 16.04.2009

Сообщений: 127

03.05.2009, 19:32

 [ТС]

5

Да, 2 матрицы

Код

	int m1[20];
	double m2[20];

Чем они заполнены писать не буду, не суть важно



0



MCSD: APP BUILDER

8794 / 1073 / 104

Регистрация: 17.06.2006

Сообщений: 12,603

03.05.2009, 19:43

6

PMike,
Проскочила такая новость, что сегодня в 21:00 по Москве закрывают Гоогле, так что поторопись, а то потом будет позняк метаться:
google.ru => «datagridview example»



4



1507 / 774 / 103

Регистрация: 22.04.2008

Сообщений: 1,610

03.05.2009, 20:10

7

Просто так эти матрицы точнее векторы не предствишь в DataGridView надо чтобы
данные которые вы хотите выводить в DataGridView были унаследованы от IList.



0



3 / 3 / 1

Регистрация: 16.04.2009

Сообщений: 127

03.05.2009, 21:15

 [ТС]

8

И как это сделать?



0



akasex

48 / 49 / 10

Регистрация: 24.12.2008

Сообщений: 75

03.05.2009, 22:38

9

int m1[20];
double m2[20];

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
DataTable dt = new DataTable();
dt.Columns.Add("Column1");
dt.Columns.Add("Column2");
 
for (int i = 0; i < 20; i++)
{
       DataRow r = dt.NewRow();
       r["Column1"] = m1[i];
       r["Column2"] = m2[i];
       dt.Rows.Add(r);
}
 
dataGridView1.DataSource = dt;
...



1



3 / 3 / 1

Регистрация: 16.04.2009

Сообщений: 127

04.05.2009, 08:43

 [ТС]

10

akasex, огромное спасибо! все работает!

Добавлено через 9 минут 32 секунды
А как сделать чтобы последняя строчка со звездочкой не отображалась?



0



1922 / 427 / 41

Регистрация: 12.07.2007

Сообщений: 2,062

04.05.2009, 09:01

11

dataGridView1.AllowUserToAddRows = false;



2



3 / 3 / 1

Регистрация: 16.04.2009

Сообщений: 127

04.05.2009, 14:09

 [ТС]

12

А как сделать чтобы таблица по горизонтали заполняла все пространство dataGridView?

Добавлено через 4 часа 57 минут 52 секунды
Последний вопрос отпал сам собой. Все спасибо за ответы!



0



Привязка данных

Эта глава основана на материалах главы 26, в которой описаны различные способы извлечения и изменения данных, и посвящена представлению данных для пользователей с привязкой данных к различным элементам управления Windows. Точнее говоря, здесь будут обсуждаться следующие вопросы:

отображение данных с помощью элемента управления DataGridView;

возможности привязки данных .NET и как они работают;

как использовать проводник по серверу Server Explorer для создания соединения и генерации класса DataSet (не написав ни единой строки кода);

как использовать проверку попаданий и рефлексию строк DataGrid.

Коды примеров этой главы доступны на прилагаемом компакт-диске.

Элемент управления DataGridView

Элемент управления DataGrid, доступный начиная с ранних выпусков .NET, был вполне функциональным, но имел множество недоработок, которые делали его неподходящим для применения в коммерческих приложениях, например, отсутствовала возможность вывода графических изображений и раскрывающихся элементов, блокировка столбцов и тому подобное. Этот элемент управления был не вполне полноценным, поэтому многие независимые поставщики предлагали собственные сеточные компоненты, которые компенсировали эти недостатки и представляли гораздо более широкую функциональность.

В .NET 2.0 появился дополнительный сеточный элемент управления — DataGridView. Он восполнил многие недостатки своего предшественника и добавил важную функциональность, которая до этого была реализована лишь в продуктах независимых поставщиков.

Этот элемент оснащен такими же средствами привязки данных, как и старый DataGrid, а потому может работать совместно с классами Array, DataTable, DataView или DataSet либо компонентами, реализующими интерфейс IListSource или IList. Элемент управления DataGridView обеспечивает возможности разнообразного представления одних и тех же данных. В простейшем случае отображаемые данные (такие как из DataSet) указываются установкой значений свойств DataSource и DataMember. Отметим, что этот элемент управления не может подставляться вместо DataGrid, потому что его программный интерфейс полностью отличается от интерфейса DataGrid. К тому же он предлагает более широкие возможности, о которых мы и поговорим в этой главе.

1102 Часть V. Презентации

Отображение табличных данных

В главе 19 было представлено множество способов выбора данных и чтения их в таблицы, хотя отображались они очень примитивным способом — с использованием

Console.WriteLine().

Следующий пример демонстрирует, как извлечь данные и отобразить их в элементе управления DataGridView. Для этой цели мы создадим новое приложение DisplayTabularData, внешний вид которого показан на рис. 32.1.

Рис. 32.1. Внешний вид приложения DisplayTabularData

Это простое приложение выбирает каждую запись из таблицы Customer базы данных Northwind и отображает эти записи пользователю в элементе управления DataGridView. Ниже показан код этого примера (исключая код определения формы и элемента управления).

using System;

using System.Configuration; using System.Data;

using System.Data.Common; using System.Data.SqlClient; using System.Windows.Forms; namespace DisplayTabularData

{

partial class Form1: Form

{

public Form1()

{

InitializeComponent();

}

private void getData_Click(object sender, EventArgs e)

{

string customers = «SELECT * FROM Customers»;

using (SqlConnection con = new SqlConnection (ConfigurationManager. ConnectionStrings[«northwind»].ConnectionString))

{

DataSet ds = new DataSet();

SqlDataAdapter da = new SqlDataAdapter(customers, con); da.Fill(ds, «Customers»); dataGridView.AutoGenerateColumns = true; dataGridView.DataSource = ds;

dataGridView.DataMember = «Customers»;

}

}

}

}

Глава 32. Привязка данных 1103

Форма состоит из кнопки getData, в результате щелчка на которой вызывается метод getData_Click(), показанный в коде примера.

При этом конструируется объект SqlConnection, использующий свойство

ConnectionStrings класса ConfigurationManager. Далее создается набор данных и заполняется на основе таблицы базы данных с помощью объекта DataAdapter. Затем эти данные отображаются элементом управления DataGridView за счет установки свойств DataSource и DataMember.

Отметим, что свойству AutoGenerateColumns также присваивается значение true, поскольку это гарантирует, что пользователь что-то увидит. Если этот флаг не установлен, все столбцы придется создавать самостоятельно.

Источники данных

Элемент управления DataGridView предлагает гибкий способ отображения данных; в дополнение к установке DataSource равным DataSet, а DataMember — равным имени отображаемой таблицы, свойство DataSource может указывать на любой из следующих источников:

массив (визуальная таблица может быть связана с любым одномерным массивом);

DataTable;

DataView;

DataSet или DataViewManager;

компоненты, реализующие интерфейс IListSource;

компоненты, реализующие интерфейс IList;

любой обобщенный класс коллекции или объект, унаследованный от обобщенного класса коллекции.

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

Отображение данных из массива

На первый взгляд это кажется простым. Нужно создать массив, наполнить его некоторыми данными и установить свойство DataSource элемента управления DataGridView. Вот пример кода:

string[] stuff = new string[] {«One», «Two», «Three»}; dataGridView.DataSource = stuff;

Если источник данных включает множество возможных таблиц-кандидатов (как в случае с DataSet или DataViewManager), также понадобится установить свойство DataMember.

Можно заменить этим кодом код события getData_ Click из предыдущего примера. Проблема с этим кодом проявляется в отображении данных (рис. 32.2).

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

гося в массиве, вместо строкового значения. Первое Рис. 32.2. Проблема, связанная (и единственное) общедоступное свойство строки — с примером кода

1104 Часть V. Презентации

это длина, потому она и отображается. Список свойств каждого класса может быть получен с помощью метода

GetProperties класса TypeDescriptor. Он возвращает коллекцию объектов PropertyDescriptor, которая затем может использоваться для отображения данных. Элемент управления .NET PropertyGrid применяет этот метод для отображения произвольных объектов.

Один из способов решения этой проблемы с отображением строк в DataGridView заключается в создании класса-оболочки:

protected class Item

{

public Item(string text)

{

_text = text;

}

public string Text

{

get{return _text;}

}

private string _text;

}

Рис. 32.3. Вывод массива объектов класса Item

На рис. 32.3 показан вывод массива объектов класса Item (который может быть и структурой), служащего источником данных.

DataTable

DataTable можно отображать в элементе управления DataGridView двумя способами:

если используется DataTable сама по себе, следует просто установить свойство DataSource элемента управления на эту таблицу;

если DataTable входит в DataSet, необходимо установить DataSource на DataSet, а свойство DataMember — равным имени DataTable внутри этого DataSet.

На рис. 32.4 показан результат запуска кода примера DataSourceDataTable. Обратите внимание на отображение последнего столбца — он показывает флаж-

ки вместо более привычных полей редактирования. Дело в том, что элемент управления DataGridView в отсутствие любой другой информации будет читать схему из источника данных (в данном случае — таблицы Products) и на основе типа столбца автоматически выбирать тип элемента управления, отображающего его. В отличие от DataGrid, DataGridView имеет встроенную поддержку столбцов с изображениями, кнопками и комбинированными списками.

Рис. 32.4. Результат запуска кода примера DataSourceDataTable

Глава 32. Привязка данных 1105

Данные в базе не изменяются, когда изменяются поля в визуальной таблице, поскольку ее данные хранятся локально на клиентском компьютере — нет никакого активного подключения к базе данных. Обновление данных в базе мы обсудим в этой главе позднее.

Отображение данных из DataView

DataView предоставляет средства фильтрации и сортировки данных внутри DataTable. Когда данные выбираются из базы, обычно пользователю разрешено сортировать их, например, щелчком на заголовке того или иного столбца. В дополнение пользователь может пожелать отфильтровать данные, чтобы показать только определенные строки, например, те, что подверглись изменениям. DataView можно фильтровать так, что только выбранные строки будут показаны пользователю; однако это не ограничивает столбцы из DataTable.

DataView не позволяет фильтровать столбцы, а только строки.

Чтобы создать DataView на базе существующей DataTable, нужно использовать следующий код:

DataView dv = new DataView(dataTable);

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

установка AllowEdit = false отключает всю функциональность редактирования столбцов в строках;

установка AllowNew = false отключает функциональность новых строк;

установка AllowDelete = false отключает возможность удаления строк;

установка RowStateFilter отображает только строки с заданным состоянием;

установка RowFilter позволяет фильтровать строки на основе выражений.

В следующем разделе будет показано, как использовать настройки RowFilter и RowStateFilter; остальные настройки объяснений не требуют.

Фильтрация строк на основе данных

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

В табл. 32.1 показаны некоторые примеры конструкций фильтрации. Исполняющая система старается наилучшим образом подогнать типы данных в вы-

ражениях фильтра к соответствующим типам исходных столбцов. Например, вполне допустимо было в предыдущем примере написать UnitsInStock > ’50’ несмотря на то, что столбец имеет целочисленный тип. Если указывается неправильное выражение фильтра, это приводит к возбуждению исключения EvaluateException.

1106 Часть V. Презентации

Таблица 32.1. Примеры конструкций фильтрации

Конструкция

Описание

UnitsInStock > 50

Показывает только те строки, в которых значение столбца UnitsInStock

больше 50.

Client = ‘Smith’

County LIKE ‘C*’

Возвращает записи для заданного клиента.

Возвращает все записи, в которых поле Country начинается с C — в данном примере будут возвращены строки со следующими значениями

Country: Cornwall, Cumbria, Cheshire и Cambridgeshire. Символ %

может использоваться как односимвольный шаблон, в то время как * — обобщенный шаблон, которому соответствует ноль или более символов.

Фильтрация на основе состояния строк

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

Таблица 32.2. Допустимые состояния строк

DataViewRowState

Описание

Added

Список всех вставленных строк.

CurrentRows

Список всех строк за исключением удаленных.

Deleted

Список всех исходных строк, которые были выделены и удалены;

вновь созданные и тут же удаленные строки не отображаются.

ModifiedCurrent

Список всех измененных строк с их текущими значениями.

ModifiedOriginal

Список всех измененных строк в их исходном состоянии (до изменения).

OriginalRows

Список всех строк, которые были изначально получены от источника дан-

ных. Не включает новые строки. Показывает исходные значения столбцов

(то есть те, что были до внесения изменений).

Unchanged

Список всех строк, которые не были изменены.

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

Фильтр не только применяется к видимым строкам, но также и к столбцам внутри этих строк. Это наглядно демонстрирует выбор ModifiedOriginal или ModifiedCurrent. Доступные состояния описаны в главе 20 и основаны на перечислении DataRowVersion.

Например, когда пользователь обновляет столбец в строке, то эта строка будет отображена как при выборе ModifiedOriginal, так и при ModifiedCurrent; однако действительным значением будет либо исходное значение Original, полученное из базы данных (если выбрано ModifiedOriginal), либо текущее измененное значение

DataColumn (в случае выбора ModifiedCurrent).

Сортировка строк

Помимо фильтрации, данные в DataView можно также сортировать. Сортировка выполняется по возрастанию или по убыванию — простым щелчком на заголовке столбца в элементе управления DataGridView (рис. 32.6).

Глава 32. Привязка данных 1107

Рис. 32.5. Пример с двумя таблицами

Рис. 32.6. Сортировка с использованием элемента управления DataGridView

Единственная проблема состоит в том, что сортировать можно только по одному столбцу, в то время как лежащий в основе элемент управления DataView может сортировать по множеству столбцов. Когда столбец сортируется — либо щелчком на его заголовке (как показано, на столбце ProductName), либо программно — DataGrid показывает в его заголовке изображение стрелочки для пометки, по какому столбцу выполнена сортировка.

Программная установка порядка сортировки реализуется путем присвоения свойству Sort в DataView соответствующего значения:

dataView.Sort = «ProductName»;

dataView.Sort = «ProductName ASC, ProductID DESC»;

Первая строка сортирует данные по значению столбца ProductName, что можно видеть на рис. 32.6. Вторая строка сортирует данные в возрастающем порядке по

ProductName и в убывающем — по ProductID.

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

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

1108 Часть V. Презентации

Отображение данных из класса DataSet

Существует одно средство DataSet, которое отличает DataViewGrid от DataGrid — это когда DataSet определяет отношение между таблицами. Как в приведенных выше примерах с DataViewGrid, DataGrid может одновременно отображать только одну таблицу. Однако, как показано в следующем примере с DataSourceDataSet, можно выполнять навигацию по отношениям внутри DataSet в пределах одного экрана. Следующий код можно использовать для генерации такого DataSet на основе таблиц Customers и Orders базы данных Northwind. Этот пример загружает данные из этих двух DataTable и затем создает отношение между ними под названием CustomerOrders:

string orders = «SELECT * FROM Orders»; string customers = «SELECT * FROM Customers»;

SqlConnection conn = new SqlConnection(source); SqlDataAdapter da = new SqlDataAdapter(orders, conn); DataSet ds = new DataSet();

da.Fill(ds, «Orders»);

da = new SqlDataAdapter(customers , conn); da.Fill(ds, «Customers»); ds.Relations.Add(«CustomerOrders»,

ds.Tables[«Customers»].Columns[«CustomerID»],

ds.Tables[«Orders»].Columns[«CustomerID»]);

Созданный DataSet связывается с DataGrid простым вызовом SetDataBinding():

dataGrid1.SetDataBinding(ds, «Customers»);

Это даст вывод, показанный на рис. 32.7.

В отличие от других примеров DataGridView, приведенных с этой главе, здесь мы видим знак + слева от каждой записи. Это отражает тот факт, что DataSet имеет управляемое отношение между заказчиками и заказами. В коде можно определить любое количество таких отношений.

Когда пользователь щелкает на знаке +, отображается список отношений (или скрывается — если ранее он был отображен). Щелчок на имени отношения позволяет перейти к связанным записям (рис. 32.8); в данном примере — к списку заказов, размещенных выбранным заказчиком.

Рис. 32.7. Знаки + слева от каждой записи обозначают отношения между заказчиками и заказами

Глава 32. Привязка данных 1109

Рис. 32.8. Связанные записи, отображаемые в результате щелчка на имени отношения

Элемент управления DataGrid также включает пару новых пиктограмм в правом верхнем углу. Пиктограмма со стрелкой влево позволяет перейти к родительской записи и вернет экран к состоянию, показанному на предыдущей странице. Вторая пиктограмма служит для того, чтобы показать/скрыть детальную информацию о родительской записи в строке заголовка.

Отображение данных в DataViewManager

Отображение данных в DataViewManager — такое же, как для DataSet, показанное в предыдущем разделе. И потому для отображения только заказчиков из Великобритании (UK), содержащихся в таблице Customers, необходим следующий код:

DataViewManager dvm = new DataViewManager(ds); dvm.DataViewSettings[«Customers»].RowFilter = «Country=’UK'»; dataGrid.SetDataBinding(dvm, «Customers»);

На рис. 32.9 показан вывод примера кода DataSourceDataViewManager.

Рис. 32.9. Вывод примера кода DataSourceDataViewManager

Интерфейсы IListSource и IList

DataGridView также поддерживает любые объекты, которые реализуют интерфейсы IListSource или IList. Интерфейс IListSource имеет только один метод — GetList(), который возвращает интерфейс IList. В свою очередь, IList пред-

1110 Часть V. Презентации

ставляет собой нечто более интересное. Этот интерфейс реализуют многие классы исполняющей системы. Среди них — Array, ArrayList и StringCollection.

Когда используется IList, в силе остается то же предупреждение относительно объектов, содержащихся в коллекции, которое было упомянуто ранее в примере с Array в качестве источника данных, а именно — если источником данных DataGrid служит StringCollection, то в визуальной таблице отображаются длины строк, а не их текст, как ожидалось.

Отображение обобщенных коллекций

В дополнение к уже описанным типам, DataGridView также поддерживает привязку к обобщенным коллекциям. При этом применяется такой же синтаксис, как и в других примерах, приведенных ранее в этой главе — нужно просто установить свойство DataSource в ссылку на коллекцию, и элемент управления сгенерирует соответствующий экран.

Опять-таки, отображаемые столбцы основаны на свойствах объекта — все общедоступные читаемые поля отображаются в DataGridView. В следующем примере демонстрируется отображение списочного класса.

class PersonList : List < Person >

{

}

class Person

{

public Person( string name, Sex sex, DateTime dob )

{

_name = name; _sex = sex;

_dateOfBirth = dob;

}

public string Name

{

get { return _name; } set { _name = value; }

}

public Sex Sex

{

get { return _sex; } set { _sex = value; }

}

public DateTime DateOfBirth

{

get { return _dateOfBirth; } set { _dateOfBirth = value; }

}

private string _name; private Sex _sex;

private DateTime _dateOfBirth;

}

enum Sex

{

Male,

Female

}

Экран показывает несколько экземпляров класса Person, которые сконструированы внутри класса PersonList (рис. 32.10).

Понравилась статья? Поделить с друзьями:
  • Как добавить системную переменную windows 10
  • Как добавить съемный диск в мой компьютер в windows 10
  • Как добавить симс 4 в исключения антивируса windows 10
  • Как добавить схему электропитания windows 10
  • Как добавить сеть вай фай на ноутбуке вручную windows