Witam, temat trochę długi i może na pierwszy rzut oka nie czytelny problem. Ale już tłumaczę o co dokładnie chodzi.
W aplikacji którą tworzę będzie spora ilość DataGridView dla różnych części systemu np. dla formatki odpowiedzialnej za zarządzanie użytkownikami, kontrahentami, itp. Zamieszczam również kod, może komuś się przyda, a może ktoś inny zauważy rażące błedy i zaproponuje ich rozwiązanie. Stworzyłem mini toolBox dla DataGridView, klasa 'ToolBoxDataGridView' udostępnia między innymi obrazki, które zmieniają np. wizualizację, kopiują zaznaczone elementy DataGridView, itp. Są tam również funkcje odpowiedzialne za tworzenie TextBox'ów odpowiedzialnych za filtrowanie wierszy DataGridView według kolumn... Formatka zarządzająca urzytkownikami pobiera metody do obsługi elementów z klasy SystemBase, klasa ta udostępnia wszystkie niezbędne jej metody między innymi: sb.FillUser(ref DataGridView dgw, ref Label lbl, List<TextBox> listTB); Dodatkowo formatka zarządzająca użytkownikami wywołuje klasę ToolBoxDataGridView. Problem zaczyna się w momencie gdy użytkownik wpisuje tekst do TextBox'ów, które sortują w zdarzeniu TextBox_Changed, nie mam wskaźnika do klasy SystemBase i metody FillUser. Czytałem o delegatach, ale nic co znalazłem nie ułatwiło mi rozwiązania problemu. W załączniku przesyłam print screna z formatki. Mógłbym oczywiscie przekazać oolBoxDataGridView dostęp do klasy SystemBase, ale jest to całkowicie nie porządane :/ Bo klas podobnych do SystemBase będzie kilka... wolałbym użyć delegata tylko na chwilę obecną w ogóle mi to nie wychodzi...
public class ToolBoxDataGridView
{
private DataGridView dgv = null;
private ImageList image16x16 = null;
private Panel p = null;
private PictureBox pbSelectAll = new PictureBox();
private PictureBox pbCopy = new PictureBox();
private PictureBox picPrinter = new PictureBox();
private PictureBox picPDF = new PictureBox();
private PictureBox picXLS = new PictureBox();
private PictureBox picSelectFullRow = new PictureBox();
private PictureBox picBorder = new PictureBox();
private PictureBox picTextBox = new PictureBox();
private List<TextBox> lTb;
private bool afterLoad = false;
private int firstColumnVisable, lastColumnVisable = 0;
private int shiftTextBox = 0;
public void SetPanel(ref Panel p)
{
this.p = p;
this.p.Controls.Add(pbSelectAll);
this.p.Controls.Add(pbCopy);
this.p.Controls.Add(picPrinter);
this.p.Controls.Add(picPDF);
this.p.Controls.Add(picXLS);
this.p.Controls.Add(picSelectFullRow);
this.p.Controls.Add(picBorder);
this.p.Controls.Add(picTextBox);
}
public List<TextBox> GetListTextBoxForFiltrDataGridView()
{
return lTb;
}
public ToolBoxDataGridView(Point p, ImageList image16x16, ref DataGridView dgv, ref Panel panel, ref List<TextBox> lTb)
{
this.dgv = dgv;
this.image16x16 = image16x16;
this.p = panel;
this.lTb = lTb;
CreateTextBoxFiltrForDataGridView();
pbSelectAll.Location = p;
pbSelectAll.Size = new System.Drawing.Size(16, 16);
pbSelectAll.Image = this.image16x16.Images["table_select_all.png"];
pbSelectAll.TabIndex = 1;
pbSelectAll.Visible = true;
pbSelectAll.Click += new System.EventHandler(this.pbSelectAll_Click);
this.p.Controls.Add(pbSelectAll);
p.X += 22;
pbCopy.Location = p;
pbCopy.Size = new System.Drawing.Size(16, 16);
pbCopy.Image = this.image16x16.Images["page_copy.png"];
pbCopy.TabIndex = 2;
pbCopy.Visible = true;
pbCopy.Click += new System.EventHandler(this.pbpbCopy_Click);
this.p.Controls.Add(pbCopy);
p.X += 22;
picPrinter.Location = p;
picPrinter.Size = new System.Drawing.Size(16, 16);
picPrinter.Image = this.image16x16.Images["printer.png"];
picPrinter.TabIndex = 3;
picPrinter.Visible = true;
picPrinter.Click += new System.EventHandler(this.printer_Click);
this.p.Controls.Add(picPrinter);
p.X += 44;
picPDF.Location = p;
picPDF.Size = new System.Drawing.Size(16, 16);
picPDF.Image = this.image16x16.Images["file_extension_pdf.png"];
picPDF.TabIndex = 4;
picPDF.Visible = true;
picPDF.Click += new System.EventHandler(this.picPDF_Click);
this.p.Controls.Add(picPDF);
p.X += 22;
picXLS.Location = p;
picXLS.Size = new System.Drawing.Size(16, 16);
picXLS.Image = this.image16x16.Images["file_extension_xls.png"];
picXLS.TabIndex = 5;
picXLS.Visible = true;
picXLS.Click += new System.EventHandler(this.picXLS_Click);
this.p.Controls.Add(picXLS);
p.X += 44;
picTextBox.Location = p;
picTextBox.Size = new System.Drawing.Size(16, 16);
picTextBox.Image = this.image16x16.Images["textfield_add.png"];
picTextBox.TabIndex = 7;
picTextBox.Visible = true;
picTextBox.Click += new System.EventHandler(this.picTextBox_Click);
this.p.Controls.Add(picSelectFullRow);
p.X += 22;
picSelectFullRow.Location = p;
picSelectFullRow.Size = new System.Drawing.Size(16, 16);
picSelectFullRow.Image = this.image16x16.Images["table_select_big.png"];
picSelectFullRow.TabIndex = 6;
picSelectFullRow.Visible = true;
picSelectFullRow.Click += new System.EventHandler(this.picSelectFullRow_Click);
this.p.Controls.Add(picBorder);
p.X += 22;
picBorder.Location = p;
picBorder.Size = new System.Drawing.Size(16, 16);
picBorder.Image = this.image16x16.Images["border_1.png"];
picBorder.TabIndex = 7;
picBorder.Visible = true;
picBorder.Click += new System.EventHandler(this.picBorder_Click);
this.p.Controls.Add(picTextBox);
}
private void pbSelectAll_Click(object sender, EventArgs e)
{
this.dgv.SelectAll();
}
private void pbpbCopy_Click(object sender, EventArgs e)
{
if (this.dgv.SelectedRows.Count > 0)
{
DataObject data = this.dgv.GetClipboardContent();
Clipboard.SetDataObject(data, true);
}
}
private void printer_Click(object sender, EventArgs e)
{
}
private void picPrinter_Click(object sender, EventArgs e)
{
}
private void picPDF_Click(object sender, EventArgs e)
{
}
private void picXLS_Click(object sender, EventArgs e)
{
}
private void picSelectFullRow_Click(object sender, EventArgs e)
{
if (this.dgv.SelectionMode == DataGridViewSelectionMode.FullRowSelect)
{
this.dgv.SelectionMode = DataGridViewSelectionMode.CellSelect;
this.picSelectFullRow.Image = this.image16x16.Images["table_select_row.png"];
}
else
{
this.dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
this.picSelectFullRow.Image = this.image16x16.Images["table_select_big.png"];
}
}
private void picBorder_Click(object sender, EventArgs e)
{
switch (this.dgv.CellBorderStyle)
{
case DataGridViewCellBorderStyle.Sunken:
{
this.dgv.CellBorderStyle = DataGridViewCellBorderStyle.None;
this.picBorder.Image = this.image16x16.Images["border_1_none.png"];
}
break;
case DataGridViewCellBorderStyle.None:
{
this.dgv.CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal;
this.picBorder.Image = this.image16x16.Images["border_1_hor.png"];
}
break;
case DataGridViewCellBorderStyle.SingleHorizontal:
{
this.dgv.CellBorderStyle = DataGridViewCellBorderStyle.Sunken;
this.picBorder.Image = this.image16x16.Images["border_1.png"];
}
break;
}
}
private void picTextBox_Click(object sender, EventArgs e)
{
if (this.picTextBox.Name == "textfield_delete")
{
this.picTextBox.Image = this.image16x16.Images["textfield_add.png"];
this.picTextBox.Name = "textfield_add";
foreach (TextBox tb in this.lTb)
{
tb.Visible = false;
}
}
else
{
afterLoad = true;
CheckLocationAndWidthTextBox();
foreach (TextBox tb in this.lTb)
{
tb.Visible = true;
}
this.picTextBox.Image = this.image16x16.Images["textfield_delete.png"];
this.picTextBox.Name = "textfield_delete";
}
}
private void CreateTextBoxFiltrForDataGridView()
{
int nextTextBoxLocationX = 0;
for (int i = 0; i < dgv.ColumnCount; i++)
if (dgv.Columns[i].Visible == true)
{
TextBox tb = new TextBox();
if (nextTextBoxLocationX == 0)
nextTextBoxLocationX = dgv.Location.X + dgv.RowHeadersWidth;
tb.Location = new Point(nextTextBoxLocationX, dgv.Location.Y - 24);
tb.Name = dgv.Columns[i].Name;
tb.Width = dgv.Columns[i].Width - 1;
tb.Visible = false;
tb.TextChanged += new System.EventHandler(this.TextBox_Changed);
this.p.Controls.Add(tb);
this.lTb.Add(tb);
nextTextBoxLocationX += dgv.Columns[i].Width + 1;
// Wyznaczenie pierwszej widocznej tabeli
if (firstColumnVisable == 0)
firstColumnVisable = i;
// Wyznaczenie ostatniej widocznej tabeli
lastColumnVisable = i;
}
}
private void CheckLocationAndWidthTextBox()
{
// Lokalna zmienna przechowująca przesunięcie dla poszczególnych TextBox'ów
int localShiftTextBox = dgv.Location.X + dgv.RowHeadersWidth;
// Pętla wyszukująca wszystkie kolumny dla których wartość Visible = true
for (int i = 0; i < dgv.ColumnCount; i++)
// Sprawdzenie czy wartość Visible kolumny = true
if (dgv.Columns[i].Visible == true)
// Pętla wyszukująca wszystkie TextBox'y odpowiadające za filtrowanie danych
foreach (TextBox tb in lTb)
{
// Porównanie nazwy kolumny z nazwą TextBox'a
if (tb.Name == dgv.Columns[i].Name)
{
// Zmiana pozycji TextBox'a
tb.Location = new Point(localShiftTextBox, dgv.Location.Y - 24);
// Zmiana długości TextBox'a
tb.Width = dgv.Columns[i].Width - 1;
// Dodanie do wartości przesunięcia wartość TextBox'a dla którego wywołano zdarzenie
localShiftTextBox += dgv.Columns[i].Width + 1;
}
}
}
public void ChcengeWidthTextBox(string column_name)
{
// Sprawdzenie czy wczytano już cały DataGridView
// Jeżeli tak algorytm ustawia długość poszczególnych TextBox'ów
if (this.afterLoad == true)
{
// Sprawdzenie czy algorytm wykonuje dla pierwszego TextBox'a
if (shiftTextBox == 0)
{
// Zmienna 'shiftTextBox' przechowuje przesunięcie
// Początkowa wartość to DataGridView.Location.X (lokalizacja) + DataGridView.RowHeadersWidth (margines)
shiftTextBox = dgv.Location.X + dgv.RowHeadersWidth;
// Sprawdzenie czy przesuwana kolumna nie jest pierwszą
// Jeżeli nie jest należy do wartości 'shiftTextBox' dodać długość wcześniejszych TextBox'ów
if (dgv.Columns[firstColumnVisable].Name != column_name)
{
// Pętla sumująca długości wcześniejszych TextBox'ów
// Działa do momentu natrafienia na kolumnę przesuwaną przez użytkownika
foreach (TextBox tb in this.lTb)
{
if (tb.Name == column_name)
break;
else
shiftTextBox += tb.Width + 2;
}
}
}
// Pętla wszykująca TextBox'a któego nazwa odpowiada nazwie kolumny dla której wywołano zdarzenie
foreach (TextBox tb in this.lTb)
{
// Sprawdzenie czy dla tego TextBox'a wywołano zdarzenie
if(tb.Name == column_name)
{
// Zmiana pozycji TextBox'a
tb.Location = new Point(shiftTextBox, dgv.Location.Y - 24);
// Zmiana długości TextBox'a
tb.Width = dgv.Columns[column_name].Width - 1;
// Dodanie do wartości przesunięcia wartość TextBox'a dla którego wywołano zdarzenie
shiftTextBox += dgv.Columns[column_name].Width + 1;
}
}
}
if (dgv.Columns[column_name].Index == lastColumnVisable)
shiftTextBox = 0;
// Do ustalenia ostatniego widocznego kolumny
// MessageBox.Show(dgv.Columns[column_name].Index.ToString());
}
private void TextBox_Changed(object sender, EventArgs e)
{
//TextBox tb = (TextBox) sender;
//MessageBox.Show(tb.Name.ToString() + " " + tb.Text);
}
}