i have that code in my desktop application that fill the datagrid from mysql database
var mA = new MySql.Data.MySqlClient.MySqlDataAdapter("SELECT * FROM items", DataHolder.MySqlConnection);
var mT = new System.Data.DataTable();
mA.Fill(mT);
dataGrid.ItemsSource = mT.DefaultView;
but i can't figure out how to bind it to change certain cells in certain column to change it's background color when it's equl to certain values.
I have read Change DataGrid cell colour based on values, but in my case there is no columns to bind in the Data Grid until the code is executed. What I am asking is "how to make it work with that"?!
i know how to change the background color for datagrid that already have columns in it but in that case there isn't no columns to bind in the datagrid until the code is executed
This implies that you are using the auto generated columns. You just need to hook AutoGeneratingColumn or AutoGeneratedColumns, which give you access to the new columns in the event args, which you then can style accordingly (would recommend defining styles in XAML resources somewhere).
Related
I'm dynamically creating a WPF window with a grid-like presentation. There is a header row that contains the column headers. It must always be visible. Below that there is a large number of rows (like hundreds) that can be vertically scrolled. Each row contains a text in the first column and a checkbox in each remaining column.
The list of columns and rows is dynamic, so creating a viewmodel class and binding with templates doesn't work (or would at least be very complicated and require much code while giving up the dynamic nature of the problem). Also, with each checkbox interaction in one row, all other rows might be affected (for the same column) and need to be updated. This would need a lot of interaction between all individual row viewmodels.
I'm looking for a solution to create the columns and rows of an existing empty ListView control and populate all of its data, checkboxes and interaction entirely in C# code.
Specifically I'm missing some ListView method that lets me set the content of a specific cell. While I can add columns to the ListView's GridView.Columns collection, I can't go anywhere from there without templates and bindings. Is is possible to use WPF like this?
The problem is that when I use a template for, say, a checkbox column, all checkboxes do exactly the same an no customisation is possible anymore because I don't create each checkbox, instead WPF creates them for me.
You may create a specific CellTemplate for each GridViewColumn using either XamlReader.Parse:
const string Xaml = "<DataTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x = \"http://schemas.microsoft.com/winfx/2006/xaml\">" +
"<CheckBox Content=\"{Binding Name}\" IsChecked=\"{Binding IsChecked}\" />" +
"</DataTemplate>";
column.CellTemplate = XamlReader.Parse(Xaml) as DataTemplate;
...or a FrameworkElementFactory:
FrameworkElementFactory checkBox = new FrameworkElementFactory(typeof(CheckBox));
checkBox.SetBinding(CheckBox.ContentProperty, new Binding("Name"));
checkBox.SetBinding(CheckBox.IsCheckedProperty, new Binding("IsChecked"));
column.CellTemplate = new DataTemplate() { VisualTree = checkBox };
This lets you customize the columns but still use the GridView and its functionlity the way you are supposed to. Trying to modifying the generated visual elements is not recommended, especially not if you are using the UI virtualization.
I would really like to change the style of the selected item of a single DataGridVeiwComboBox control.
There is a database that feeds information into my DataGridView, and if for some reason, the data is invalid, I would like to notify the user somehow. I have decided to make the dropdown text font red, and background blue so it can stand out in a list of hundreds of rows.
When there is invalid data (meaning the data coming form the database is not one of the options in the dropdown list) the DataError callback is invoked:
private void OnDataError(object sender, DataGridViewDataErrorEventArgs e)
{
DataGridViewCellStyle style = new DataGridViewCellStyle();
style.ForeColor = Color.Red;
style.BackColor = Color.Blue;
((DataGridViewComboBoxCell)(((DataGridView)(sender))[e.ColumnIndex, e.RowIndex])).Style = style;
e.Cancel = true;
}
However this results in the following:
I dont want the dropdown the change, I want the '0' thats the selected value to change.
Is there another way to notify the user that the value is invalid? I dont want to create a list and present it to the user, the number of rows can be quite large.
AFAIK, there is no straightforward approach to achieve your goal.
Create custom "Column", "Cell" and "EditingControl" classes. Create custom DataGridViewComboBoxEditingControl and override the OnDrawItem method to draw the item with custom colors.
Create the required combobox column with the custom ComboBoxColumn classes, add it to the grid and bind the data. If you set the DataPropertyName property of your column then when your data is bound that data column will get bound to your grid column. The DataGridView will generate other columns automatically.
I'm adding a great deal of rows to a data grid view, and the process is pretty slow because it appears to try to redraw after each addition.
I'm having trouble finding an example online of how to create a List (or array, whichever works) of rows and add them all at once after the list is created. I need to do this to stop it from re-drawing after each addition though.
Can anyone provide a brief example of this or point me to a good doc?
You're probably looking for the DataGridView.DataSource property. See http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.datasource(v=vs.90).aspx
For example:
//Set up the DataGridView either via code behind or the designer
DataGridView dgView = new DataGridView();
//You should turn off auto generation of columns unless you want all columns of
//your bound objects to generate columns in the grid
dgView.AutoGenerateColumns = false;
//Either in the code behind or via the designer you will need to set up the data
//binding for the columns using the DataGridViewColumn.DataPropertyName property.
DataGridViewColumn column = new DataGridViewColumn();
column.DataPropertyName = "PropertyName"; //Where you are binding Foo.PropertyName
dgView.Columns.Add(column);
//You can bind a List<Foo> as well, but if you later add new Foos to the list
//reference they won't be updated in the grid. If you use a binding list, they
//will be.
BindingList<Foo> listOfFoos = Repository.GetFoos();
dgView.DataSource = listOfFoos;
A handy event to bind to at that point is the DataGridView.DataBindingComplete which fires after the data source is bound.
Here are a couple of ideas:
1) Bind a list to the DataGridView. When you set the DataGridView.DataSource = MyList, it immediately updates the entire grid without all the line-by-line action. You can add the items to MyList and then rebind to the DataGridView. (I prefer using a BindingList which will update the DataGridView grid dynamically.)
2) If data binding is not an option, what I've done in the past is set the AutoSizeMode = NotSet for each column before the update and then set it back to whatever it was before. It is the AutoSizeMode that really slows down the drawing.
I have a DataSet that I create at runtime. I would like to display this information in a datagrid using wpf and have it display certain columns chosen at runtime.
I can get the data to display using:
datagrid.ItemsSource = dataset.Tables[0].DefaultView;
datagrid.DataContext = dataset.Tables[0];
How do I use DataGridTemplateColumn to add columns to the data grid and have my dataset's information displayed in them or other arbitrary data (numeration, etc)?
Thank you.
Check if these previous StackOverflow questions answer yours:
Generating columns dynamically in the WPF DataGrid?
programatically add column & rows to WPF Datagrid
(Here is the search I used).
Basically you need to add columns to the datagrid, and set their binding (using the Binding property). There are a variety of columns to choose from, you want one that derives from DataGridBoundColumn such as DataGridTextColumn.
I want to add a DataGrid to a Form. When the program executes, the user enters values and I use those values in the problem. I need a similar implementation for a table with two columns and when the user enters values I use them to for calculation in the program.
There is no requirement to save these values to a database, they are just going to be used in the program.
How do I do this in C#?
In a winforms environment, you can bind strongly typed collections as the datasource; Each property of the objects in the collection makes a column (Strictly speaking, I believe it works out the properties for the type that the collection returns, rather than the individual items in it)
If you are writing a WinForms App then you can use a DataTable to store the data and a DataGridView to display it. Simply create the DataTable:
dataTable = new DataTable();
Create the columns you need programatically:
var columnSpec = new DataColumn();
columSpec.DataType = typeof(decimal); // If it holds a decimal
columSpec.ColumnName = "Interest Rate";
dataTable.Columns.Add(columnSpec);
Add the DataGridView to the form using the Designer - but don't and then once the table has been created bind it to the grid using:
dataGridView.DataSource = dataTable;
You can set the properties on the grid from the designer view.
I have done this in a read-only case where the DataTable is populated from the program and just displayed it. All the user can do is resize, reorder or set the visibility on the columns. To add new rows you'll need to hook into the RowsAdded event
Re-wording Rowland Shaw
You need not have a database to bind to the datagrid. If you have the data filled in a strongly typed or a generic collection you can bind the datagrid to the collection. The datagrid will fill the data from the collection.
It will take the property names as the columns, and the rows will display as per the rows in the collection.
If you want user input, then I think you should consider using a better grid control. The datagrid is not suitable for this purpose. I dont' remember if flexgrid (the ocx one) has been redone for .Net.
You can use a datagridview and build a datatable and add columns through your code and set the datatasource of your datagridview as this datatable and set AllowUserToAddRows in properties window of Dataggridview to true ( true is the default value ).
If you want to make the calculation after a full ro update is made then you can use RowPrePaint event or if you want the calculation to be made after the data in each cell gets updated then you can use the CurrentCellChanged event of the datagridview.
Hope this helps....