Change the method that meets the colors of the specified condition in DataGrid (WinForm)

xiaoxiao2021-03-06  65

Change the method that meets the colors of the specified condition in DataGrid (WinForm)

I don't know if someone will look at whether someone will look at. With the launch of Whidbey, this problem should no longer exist - the new DataGridView control is said to be able to set the color color directly - but considering whidbey is only the beta version, the DataGrid control is still widely used, this article may be faced Friends like the same question are slightly helpful.

Everyone knows that the DataGrid control controls each corresponding DataTable display style through its property tableStyles, and each TableStyle controls each of the display style of each column through its property GridColumnStyles, but there is no attribute or method to directly set the display style of each line data. . This may be considered for use (which must, if you don't know what lines in the binding data source, what data in the row), perhaps due to performance consideration (the cost of establishing a style index for each line), Or other considerations (I didn't think about ^ _ ^). But there are many demand in actual work, such as "when the resource is less than a critical value," is changed. " If you can change the color of the row, most of these needs should be met. However, in a routine method, in a column, each cell (ie, each row) display style is the same.

Changing the basic skill of the DataGrid control row color is to rewrite the PAINT method of the DataGridColumnStyle, change two parameters of Forebrush and BackBrush, and then recall the PAINT method of the base class. Of course, in practice we can't inherit the DataGridColumnStyle class, but to inherit from its subclass DataGridTextBoxColumn, DataGridBoolColumn (unfortunately we can't insert our own classes in this inheritance level, huh). As follows: public class DataGridColoredTextBoxColumn: DataGridTextBoxColumn {// Draw function overloading the cell, where the cell if the cell line ColoredView is eligible, to change the foreground and background colors protected override void Paint (System.Drawing.Graphics g, System.Drawing.Rectangle bounds, System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Brush backBrush, System.Drawing.Brush foreBrush, bool alignToRight) {/ * here is added judgment condition to decide whether to change color if (...) backbrush = new solidbrush (...); forebrush = new solidbrush (...); * / / / Drawing function Base.Paint (G, Bounds, Source, Rownum, Backbrush, Forebrush Aligntoright);}}

This method itself understands well, we will add a common method for setting up color to this class, you can specify a color when you use (here the color is a broad concept, for Brush, you can also specify the rendering method) . The key to the problem is how we set the condition in IF: We can see that the parameter ROWNUM of the Paint method gives the current line row, then can you decide to change the color of the row by specifying the line number? the answer is negative. First, the line number given by ROWNUM is the currently displayed line number, and we are either externally selected by some of the line numbers in DataSource. Since the ordering operation, the display order is changed, and the two may be inconsistent; Second, we tend to have a row of rows that meet a certain condition, rather than a row of a specific location. If the line number directly specifies, it will cause the color of the setting to become the background of DataGrid, and there is a life. In this case, we can take out the contents of the column to judge directly through ROWNUM, determine whether or not it is discolored according to its value? There are many examples on the Internet to implement, as shown in a trick, of course, is already enough, but actually use is not convenient. Because this is bound to require us to make judgment conditions ("Age> 20", "Name Like 'Jack') hardcodes in the method, not flexible enough, if there are multiple places to set different conditions, don't you write? Multiple classes? Moreover, it is not so easy to truly take out the value of a column corresponding to the ROWNUM.

To solve the above two problems, the ideal idea is to first find that ROWNUM corresponds to the corresponding line in which it is bound, and then specifies the row to be discolored by public methods, compares whether the two are equal, if equal to pre-set Brush change foreground and background. Below is a method I found to get rows in DataSource, which may not be simple enough by get a current DataView implementation, but it is indeed: // Get the current DataView DataView currentView; type itype = this.dataGridTableStyle .DataGrid.DataSource.GetType (); if (iType == typeof (System.Data.DataView)) currentView = (DataView) (this.DataGridTableStyle.DataGrid.DataSource); else if (iType == typeof (System.Data. DataTable)) currentView = ((DataTable) (this.DataGridTableStyle.DataGrid.DataSource)) DefaultView;. else if (iType == typeof (System.Data.DataSet)) currentView = ((DataSet) (this.DataGridTableStyle.DataGrid. . DataSource)) Tables [this.DataGridTableStyle.MappingName] .DefaultView; else if (iType == typeof (System.Data.DataViewManager)) {DataViewManager viewManager = (DataViewManager) (this.DataGridTableStyle.DataGrid.DataSource); currentView = viewManager .Dataset.tables [this.dataGridtablestyle.mappingname] .defaultview;} else {// If DataSource does not meet the above four types (should not be ^ _ ^), throw system error Throw (new systemException ());} // Remove the current line DATAROW CURRENTROW = CURRENTVIEW [ROWNUM] .Row; if you find the current line, it is good, and First, a series of rows, you can know if it should be discolored, as shown below: // Search if the current row is set in ColoredView in setting row, DataRow currentrow = currentview [rownum ].Row; Foreach (DataRow Coloredrow In M_ColoredDataROWS ) // m_coloredDataROWS is a DATAROW type array, which is a member variable of Private {if (currentrow == coloredrow) {backbrush = m_backbrush; forebrush = m_Forebrush; break;}} to this, we finally give the IF judgment condition, problem It is also solved.

For ease of use, we also provide a public approach, as well as several private members to set rows and colors in the outside world, which can be roughly achieved as follows: private system.data.datarow [] m_coloredDataRows; private system.drawing.brush m_Forebrush ; private System.Drawing.Brush m_backBrush; // set the color line public void SetRowsColor (DataRow [] aDataRows, System.Drawing.Brush aForeBrush, System.Drawing.Brush aBackBrush) {// set the color to change row m_coloredDataRows = aDataRows; // Set the foreground m_forebrush = AFOREBRUSH; // Set background color m_backbrush = abs aBrush;}

The method of using this class is simple. Here, one example is to use the DTABLE is a DataTable object. Use its SELECT method to select a line of changing, as a setRowsColor's argument: // Set the column and each column style DataGridTableStyle dgTableStyle = new DataGridTableStyle (); dgTableStyle.MappingName = dTable.TableName; foreach (DataColumn eachCol in dTable.Columns) {DataGridColoredTextBoxColumn dbColumnStyle = new DataGridColoredTextBoxColumn (); dbColumnStyle.MappingName = eachCol.ColumnName; // set the color line conditions and foreground and background colors dbColumnStyle.SetRowsColor (dTable.Select ( "age> 20"), new SolidBrush (Color.White), new SolidBrush (Color.BlueViolet)); dgTableStyle.GridColumnStyles.Add (dbColumnStyle);} // Add Style to DataGrid1 DataGrid1.Tables.add (DGTables.Add (DGTables); of course, if you want to be more common, there are many features to be improved, such as currently setting the color of a group of rows, replace the original content again. To set the corresponding multi-group and color, you have to add some data structures; there is only a BRUSH that can only be set, it does not change the function of changing the font, but I haven't found a good way, I haven't found a good way. There is no parameters for the font). Complete test code is attached below: use system.data;

Public class form2: system.windows.Forms.form {public form2 () {// Windows Form Designer Support for // InitializationComponent ();

DataTable DTABLE;

// Create a test DATATABLE DTABLE = New DataTable ("Person"); // Add Test Column DTable.Columns.Add (New Datacolumn ("ID", TypeOf (int))); DTABLE.COLUMNS.ADD (New Datacolumn (" Name ", TypeOf (String))); DTABLE.COLUMNS.ADD (New Datacolumn (" age ", typeof (int))))))); // Add test line DataRow newDataRow; random Irandom = new random (); for (Short I = 0; i <20; i ) {newDataRow = dtable.newrow (); newDatarow [0] = i; newDataroW [1] = Convert.TOString (Irandom.next (0,15)) "Song"; newDatarow [ 2] = iRandom.Next (15,30); dTable.Rows.Add (newDataRow);} // set the column and row of each column style DataGridTableStyle dgTableStyle = new DataGridTableStyle (); dgTableStyle.MappingName = dTable.TableName; foreach ( DataColumn eachCol in dTable.Columns) {DataGridColoredTextBoxColumn dbColumnStyle = new DataGridColoredTextBoxColumn (); dbColumnStyle.MappingName = eachCol.ColumnName; // set the color line conditions and foreground and background colors dbColumnStyle.SetRowsColor (dTable.Select ( "age> 20") New solidbrush (color.White), New solidbrush (color.blueviolet); DGTABLESTYLE.GRIDCOLUMNSTYLES.ADD (DBCOL UmnStyle);} // Add Style to DataGrid1 DataGrid1.Tables.Add (DGTables); DataGrid1.SetDataBinding (DTABLE, ");}}

public class DataGridColoredTextBoxColumn: DataGridTextBoxColumn {private System.Data.DataRow [] m_coloredDataRows; private System.Drawing.Brush m_foreBrush; private System.Drawing.Brush m_backBrush;

// set the color line public void SetRowsColor (DataRow [] aDataRows, System.Drawing.Brush aForeBrush, System.Drawing.Brush aBackBrush) {// set the color to change row m_coloredDataRows = aDataRows; // Sets the foreground color m_foreBrush = aForeBrush; // Set background color m_backbrush = Abackbrush;}

/ / Re-serve the function of the cell, if the cell is in line with the conditions in ColoredView, change the foreground and background color protected override void points (system.drawing.graphics g, system.drawing.Rectangle Bounds, System.Windows .Forms.CurrencyManager source, int rowNum, System.Drawing.Brush backBrush, System.Drawing.Brush foreBrush, bool alignToRight) {// Get DataView DataView currentView currently being displayed; Type iType = this.DataGridTableStyle.DataGrid.DataSource.GetType (); if (iType == typeof (System.Data.DataView)) currentView = (DataView) (this.DataGridTableStyle.DataGrid.DataSource); else if (iType == typeof (System.Data.DataTable)) currentView = ( (DataTable) (this.DataGridTableStyle.DataGrid.DataSource)) DefaultView;.. else if (iType == typeof (System.Data.DataSet)) currentView = ((DataSet) (this.DataGridTableStyle.DataGrid.DataSource)) Tables [ this.DataGridTableStyle.MappingName] .DefaultView; else if (iType == typeof (System.Data.DataViewManager)) {DataViewManager viewManager = (DataViewManager) (this.DataGridTableStyle.DataGrid.DataSource); currentView = ViewManager.dataset.tables [this.dataGridtablestyle.mappingname] .defaultView;} else {// If DataSource does not meet the above four types (should not be ^ _ ^), throw system error Throw (new systemException ()) ;} // set search whether the current row among rows of color ColoredView DataRow currentRow = currentView [rowNum] .Row; foreach (DataRow coloredRow in m_coloredDataRows) {if (currentRow == coloredRow) {backBrush = m_backBrush; foreBrush = m_foreBrush; break }}

// Call the drawing function of the base class Base.Paint (g, bounds, source, rower, backbrush, forebrush, aligntery);}

}

转载请注明原文地址:https://www.9cbs.com/read-111373.html

New Post(0)