Devexpress - how to add columns to multilevel gridView - c#

I'm trying to make two-level grid control. It has some package with its elements. I want to add one more column to gridView3 and hide three columns. I'm sending data to this gridView in code (dataset - 2 tables with one relation).
I've tried to send data to this gridcontrol and then operate on gridviews
gridControl2.DataSource = value.Tables[0];
gridView3.PopulateColumns(value.Tables[1]);
gridView3.Columns["RpkeId"].Visible = false;
gridView3.Columns["SourceLueId"].Visible = false;
gridView3.Columns["NewLueId"].Visible = false;
and then I'm trying to add column:
var test = new List<int> { 1, 12, 123, 1234 };
RepositoryItemComboBox riComboBox = new RepositoryItemComboBox();
riComboBox.Items.AddRange(test);
gridControl2.RepositoryItems.Add(riComboBox);
GridColumn columnGIDNumer = new GridColumn();
columnGIDNumer.FieldName = "asdfasdfa";
columnGIDNumer.ColumnEdit = riComboBox;
columnGIDNumer.OptionsColumn.AllowEdit = true;
gridView3.Columns.Add(columnGIDNumer);
None of these seem to work:
Is there any event I need to invoke or something? It seems that it'd work in normal, one-level gridcontrol.
Thanks in advance!

Related

Two different datagridview rows getting selected when one should be selected

I am working with winform project. i have two datagridview which has same number of columns and same structure. frist column is checkbox column.
here is code to bind two datagrid with same kind of data.
List<AllGroupNames> grpDtl = GetAllGroups(Nodes);
List<AllGroupNames> grpDtl1 = GetAllGroups(Nodes); //grpDtl.GetRange(0, grpDtl.Count);
//bind two grid with all groups name
if (_grpDtl != null && _grpDtl.Count > 0)
{
dgSingleGroups.AutoGenerateColumns = false;
dgSingleGroups.DataSource = grpDtl;
dgSingleGroups.Columns[0].DataPropertyName = "Select";
dgSingleGroups.Columns[1].DataPropertyName = "GroupName";
dgSingleGroups.Columns[1].ReadOnly = true;
dgSingleGroups.Columns[0].Width = 47;
dgSingleGroups.Columns[1].Width = 346;
dgAllGroups.AutoGenerateColumns = false;
dgAllGroups.DataSource = grpDtl1;
dgAllGroups.Columns[0].DataPropertyName = "Select";
dgAllGroups.Columns[1].DataPropertyName = "GroupName";
dgAllGroups.Columns[1].ReadOnly = true;
dgAllGroups.Columns[0].Width = 47;
dgAllGroups.Columns[1].Width = 346;
}
grpDtl1 = null;
grpDtl = null;
_grpDtl = null;
GetAllGroups() iterate in treeview node collection and accumulate node name.
private List<AllGroupNames> GetAllGroups(TreeNodeCollection tnCollection)
{
//accumulate group name in recursive fashion
foreach (TreeNode tn in tnCollection)
{
if (tn.Tag != null)
{
if (((object)tn.Tag).GetType().ToString().Contains("TunerDetails"))
{
_grpDtl.Add(new AllGroupNames { Select = false, GroupName = tn.Text });
}
GetAllGroups(tn.Nodes);
}
}
return _grpDtl;
}
Now problem is when i check second grid checkbox then my first grid checkbox is getting checked invisibly means when i am reading first grid's first column value in loop then i am getting checkbox value true. where as i have not checked my first grid's any checkbox.
when i select any row of second grid that same row is getting automatically selected in first grid.
I just select one row from right side grid and same row of left side grid automatically gets selected....which is problem for me. Why two grid syncing automatically. screen shot attached.
why it is happening i am not able to capture the reason. please help me what to change in code to get rid of this problem.
Apparently every object of class AllGroupName has a Boolean property Select.
You created Column[0] such, that the checkbox is checked whenever this boolean is true, and vice versa: whenever the operator checks this checkbox, the corresponding AllGroupName.Select will become true.
You decided to use the same DataSource as object in two DataGridViews.
Operator checks the checkbox of row[4] in Dgv1
This means that DataSource[4].Select = true;
This means that all objects that have this DataSource will be notified that [4] has changed
Row[4] in Dgv1 and Dgv2 will be updated: checkbox is checked.
If you don't want that changes in Dgv1 are refelected in Dgv2, then you should make a copy of the datasource.
List<...> data1 = ...; // shouldn't this be an BindingList<...> ?
Dgv1.DataSource = data1;
List<...> data2 = new List<...>(data1); // clone data1
Dgv2.DataSource = data2;

Setting DataSource to DataGridViewComboBoxColumn

I'm trying to set DataSource to DataGridViewComboBoxColumn of my DataGridView. First I'm trying to bind a data source to my DataGridView, where bindingList is a List of my custom class Plugin with properties Name (string), Id (string) and Dependencies (List):
var bindingList = PluginsHandler.GetPlugins();
var source = new BindingSource(bindingList, null);
pluginsDataGridView.AutoGenerateColumns = false;
pluginsDataGridView.DataSource = source;
pluginsDataGridView.Columns["pluginName"].DataPropertyName = "Name";
pluginsDataGridView.Columns["pluginID"].DataPropertyName = "Id";
So I can set my first two columns, but now I want to bind data to a third column of type DataGridViewComboBoxColumn. I try to do it on DataBindingComplete event:
private void pluginsDataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
for (int i = 0; i < pluginsDataGridView.Rows.Count; i++)
{
var comboCell = (DataGridViewComboBoxCell) pluginsDataGridView.Rows[i].Cells["pluginDependencies"];
var entry = pluginsDataGridView.Rows[i].DataBoundItem as IPlugin;
comboCell.DataSource = entry.Dependencies;
}
}
Sadly comboBox is empty. Funny thing happens when I incorrectly put these lines after the first block of code I posted:
var dependenciesColumn = (DataGridViewComboBoxColumn) pluginsDataGridView.Columns["pluginDependencies"];
dependenciesColumn.DataPropertyName = "Dependencies";
Then binding seem to start to work, as I can see that there are some entries in comboboxes, but when I try to hover mouse on combobox, I am getting an error that says DataGridViewComboBoxCell value is not valid).
How can I make it work?
Instead of assigning each ComboCell a data Source, set the DataSource of the column. I assume the Dependencies property of PlugIn class is a List<string>.
pluginsDataGridView.Columns["pluginDependencies"].DataSource = //list of dependencies
You have to set the DataPropertyName of the Dependencies ComboBoxColumn to get the initial values. If you don't set it you won't see any value in the column when the application is loaded.
pluginsDataGridView.Columns["pluginDependencies"].DataPropertyName = "Dependencies"
Edit:
You have a list of dependencies for a plug-in. i.e, more than one value. Usually, to select one value from list of values, you associate list with ComboBoxColumn. Achieving your requirement of multiple values from a list using standard ComboBoxColumn is difficult. Write a custom CheckedComboBoxColumn where you can display and select multiple values.

how to bind DataTable to legend in mschart

I use excel to paint a pic as follow:
please pay attention to the area hightlight in red
my question is:
how to bind the datatable to legend in mschart?
so , except the legend color, also people can see the detail data from the legend.
or, you guys can tell is it feasible to bind in mschart?
Thanks in advance!
As far as I know there is nothing in the API that allows you to simply "bind" your DataTable to a legend.
But you should still be able to manage something like that with some code:
var l = chart1.Legends[0];
l.LegendStyle = LegendStyle.Table;
l.TableStyle = LegendTableStyle.Tall;
l.BorderColor = Color.OrangeRed;
l.Docking = Docking.Bottom;
l.LegendStyle = LegendStyle.Table;
l.HeaderSeparator = LegendSeparatorStyle.DashLine;
l.HeaderSeparatorColor = Color.Red;
var firstColumn = new LegendCellColumn();
l.ColumnType = LegendCellColumnType.SeriesSymbol;
l.CellColumns.Add(firstColumn);
var secondColumn = new LegendCellColumn();
l.ColumnType = LegendCellColumnType.Text;
secondColumn.Text = "#SER";
l.CellColumns.Add(secondColumn);
foreach (DataRow row in dt.Rows)
{
var column = new LegendCellColumn();
column.ColumnType = LegendCellColumnType.Text;
column.HeaderText = row["x"].ToString();
column.Text = "#VALY";
l.CellColumns.Add(column);
}
However, my suggestion would be to include the data in a separate control, rather than as part of the chart itself. It would be much easier to work with if you kept it in one of the .net controls that's meant for tabular data, whether you're in winforms or webforms.

Winforms: How to Bind a List to multiple DataGridView

I want to be able to bind a List to multiple DataGridViews such that manipulation through one of the gridviews would be propogated to all other gridviews.
List<Domain> data;
1st approach:
BindingList<Domain> list = new ..;
data.ForEach( d => { list .Add(d); } );
grid1.DataSource = list;
grid2.DataSource = list;
This didn't work. The grids share properties other than the data.
2nd approach:
BindingList<Domain> list1 = new ..;
BindingList<Domain> list2 = new ..;
data.ForEach( d => { list1.Add(d); list2.Add(d); } );
grid1.DataSource = list1;
grid2.DataSource = list2;
This approach works for updates. However, adds and deletes weren't propograted.
3rd approach:
BindingList<Domain> list = new ..;
data.ForEach( d => { list .Add(d); } );
BindingSource ds1 = new BindingSource();
BindingSource ds2 = new BindingSource();
ds1.DataSource = list;
ds2.DataSource = list;
grid1.DataSource = ds1;
grid2.DataSource = ds2;
This propogates adds and deletes, however, when a new row is added to 1 view, but not yet commited, an empty row is displayed in all other grids. Seems like a new record is inserted into the List before the editing completes.
How can I properly bind multiple datagridviews to one List? (This is extremely easy in Flex.) I'd appreciate any reference to the relevant section in MDSN.
I made a little test app, just to make sure that sharing a binding source was possible the way I remembered. You can find it here (for at least 30 days).
What I found that propbably caused your problem is that all your grids probably have adding/deleting rows enabled. A new row in grid1 is displayed as a new row in grid2, but grid2 (quite unnecessarily) displays a template row below that.
I made a little main window with a read-only grid on a binding source and an edit dialog with an editable grid on the same binding source. The binding source is the only wiring between the two, no event handling to signal updates, no reassigning of datasources. Everything is synced perfectly, even the current row (because of the CurrencyManager). A new row in the dialog only shows as one empty row in the 'main' window.
Hope this helps, and is not over-simplified.

DataBinding a DataGridview rows BackColor

I have a DataGridView that uses databinding, with manually created columns, and this works fine.
However I want the rows' BackColor to be databound as well, and so far my attempts have hit errors.
This is my latest attempt:
dataGridFileTransfer.RowHeadersVisible = false;
dataGridFileTransfer.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridFileTransfer.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridFileTransfer.MultiSelect = false;
dataGridFileTransfer.ReadOnly = true;
var files = GetReceivedFiles(false).Union(FileDetails.Select(FileStatus.FailedVerification)).ToList();
dataGridFileTransfer.AutoGenerateColumns = false;
string[] displayHeaders = new string[] { COL_NAME, COL_TYPE, COL_CREATED, COL_SIZE, COL_STATUS };
string[] displayProps = new string[] { "Filename", "FileTypeDisplayName", "Created", "Size", "FileStatus" };
for (int i = 0; i < displayHeaders.Length; i++)
{
DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn();
col.HeaderText = displayHeaders[i];
col.DataPropertyName = displayProps[i];
if (displayHeaders[i] == COL_CREATED)
col.DefaultCellStyle.Format = Constants.DDMMYYYHHMMSS;
dataGridFileTransfer.Columns.Add(col);
}
Binding bi = new Binding("DefaultCellStyle.BackColor", files, "DisplayColor");
dataGridFileTransfer.DataBindings.Add(bi);
dataGridFileTransfer.DataSource = files;
Which is generating an ArguementException:
"Cannot bind to the property
"DefaultCellStyle.BackColor' on the
target control. Parameter name:
PropertyName"
Is it the value of PropertyName that is wrong, or should I binding to an object other than the DataGridView? (i.e. a column?)
Or is the problem that PropertyName cannot be in the form X.Y? I thought I had seen/used this syntax before, but maybe it only works for DataMember?
Any help is much appreciated
I think the problem is files.DisplayColor. files is a collection an has no property DisplayColor but each item of the collection has. So you are trying to bind a not existing property. Further binding collection DataGridView.DataBindings allows you to data bind properties of the control, not of its rows. There is only one DataGridView.DefaultCellStyle.BackColor for all rows. So I believe you end up needing to bind the DefaultCellStyle of each row to the coresponding item from files and I am not sure if this is possible. It might be that the DataGridView creates and deletes rows as required - for example if you perform filtering - and this will destroy the data binding, too.
So, I am not sure if row coloring can be done with data binding, but I personaly doubt it. This would require some really smart logic recognicing 'bind the property DisplayColor of the object data bound to this row to the property DefaultCellStyle.BackColor of this row.'
You could surly implement such an smart data binding. While it would be a great thing, it will be quite complex, too. As a simple solution you could just use the RowPrepaint event to set the correct color for the row.

Categories

Resources