DataGridView Event Before DataSource Changes - c#

Is there someway I could trigger DataSourceChanging event in DataGridView. The DataGridView has DataSourceChanged event which (I believe) after DataSource is bound to the DataGridView. I want to do some stuff before the property gets changed.
A Sample code of mine...
private void LoadGrid()
{
// I do some things like saving user settings here
DtgRefundAssign.DataSource = BLL.GetDataSource(parameter1, parameter2); //Just to illustrate
// And restore them after the datasource is bound
}
I need to do similar stuffs in many forms. Just thinking to develop a common procedure which does this, whenever the datasource is changed. The restoring part can be done using DataSourceChanged event... But which event should I handle to do the saving part ?

I haven't done this myself, but DataGridView isn't sealed so you should be able to create a new class that inherits from it. Create a new event "DataSourceChanging", then override the DataSource property's Setter so that it first raises that event, then actually sets the property on the parent class.
You'd then simply use that datagridview in place of the default one, and hook up your save logic to DataSourceChanging.

You can create a shadows/new property in the sub class using new/shadows keywords depending on whether you use c# or vb.net, since you cant override it. Use base.DataSource calls in the sub class to access the base class's property and use this.DataSource in the sub class to access the new DataSource property. :D

Related

How to create a DGV column displaying a property from partial class?

I'm writing a winforms application in C# (.NET 4.0, using EntityFramework).
I wanted to add a calculated property to an entity, which I did using a partial class. I can access new property from code, but not from designer (datasource, edmx, datagridview, ...). My datagridview is bound to a entity binding source (e.g. employeeBindingSource).
I want to add my calculated property (from partial class) to datagridview as a read-only column. The only solution that I found so far is way to messy for me ( Properties in partial class not appearing in Data Sources window! ). I'd much rather programmatically add the column.
How should I approach this?
Thank you for your time and answers.
What I did was to normally design the datagridview in designer, as much as possible (all columns except for those from partial classes). Then in my usercontrol (or form or whatever you have) constructor:
//in constructor
datagridview.AutoGenerateColumns = true;
Then in in my load event of my usercontrol I hide unwanted columns that I got because I set dgv.AutoGenerateColumns = true; And also modify header text (or whatever you need) of the column from partial class property.
//load event
employeeDataGridView.Columns[11].Visible = false;
employeeDataGridView.Columns[12].HeaderText = "Partial class prop";
I hope it will help someone.

C# Events and Control Interaction

I am currently refactoring some of my old code that is pretty terrible. I will have a class that creates a Treeview, populates the node, etc and is displayed on a Winform.
Each node on the Treeview represents some data and when the user clicks on that then a datagridview is also displayed on the Winform. The datagridview will be generated within a new class also.
My idea on this is, when the Winform Loads, create and display the Treeview and use an event to monitor for node clicks. When the Winform handles such an event, then it creates the datagrid object and diplays that.
IS this the best way to architect this?
Thanks.
Yes, what you describe is a standard way to do things in WinForms.
You don't need to create the DataGridView every time though - just place it on the Form and in the event handler load the data from somewhere and change the contents of the DataGridView by assigning to DataGridView.DataSource.
In the form designer, define columns for DataGridView and set their DataPropertyName to the names of the corresponding properties of the data objects in the collection.
Note: the data assigned to the DataGridView.DataSource can be a collection of objects or also a DataTable if you are using ADO.NET to read the objects from a database.
Just use the TreeView.AfterSelect event. It fires anytime the user selects another node, either by keyboard or mouse. Be sure to dispose the old DGV if you replace it completely.

How do you manually modify a bound object with a FormView?

I am using a FormView with an ObjectDataSource. When the save button is clicked, I would like to modify the data bound object before it gets set to the ObjectDataSources Update method.
I tried the FormView's Updating event as well as the Object Data Source's Updating event but I can't figure out how to access the data bound object. FormView.DataItem is null in those events.
Or in other words, I would like to intercept and modify the DataItem before it gets passed to the ObjectDataSource UpdateMethod.
To give a little more detail on why I want to do this, there are some values on the form which can't be databound with the build in functionality. One of the controls is the checkbox list. I am using the DataBinding event to populate the checks, but now I also need a way to update my object to reflect the form values. There are also other controls with similar situations.
I know this is an old question, but I had the same problem, and found the answer I think Bob's looking for.
The solution is to use the ObjectDataSource Updating event on the Web Form. The Updating event includes the ObjectDataSourceMethodEventArgs object as a parameter. The ObjectDataSourceMethodEventArgs class includes a propery named "InputParameters", and you can use that to access the data object and modify the contents before the update occurs. You need to convert the InputParameters object to an OrderedDictionary type first (full namespace is System.Collections.Specialized.OrderedDictionary)
It looks something like this:
protected void myObjectDataSource_Updating(object sender, ObjectDataSourceMethodEventArgs e)
{
OrderedDictionary parameters = (OrderedDictionary)e.InputParameters;
MyDataObject updatedData = (MyDataObject)parameters[0];
DropDownList myDropDown = (DropDownList)FormView1.FindControl("myDropDown")
updatedData.SomeDataValue = myDropDown.SelectedValue;
}
Why don't you just write your own business object (aka ObjectDataSource), and wrap the original ObjectDataSource object? You can then intercept anything you want, and modify it enroute to the original ObjectDataSource object's Save method.
DataItem is only available when DataBinding.
Data is then bound to controls inside your FormView.
Use myFormView.FindControl(string id) to access bound values before Updating.
If two-way databinding won't work for you, you should instanciate your object, populate manually the properties and then update or commit the changes.
Since you are in the Updating event, FormView.DataItem is null because data binding has not yet occurred. You have to access the data via the form control containing your data of interest.
Try applying your data modification during the OnDataBinding event of the relevant control.

C#: TextChanged event of a Control not firing on "assign"

Ok, here's the deal.
I have a graph, that "listens" to some labels' textfields, and graphs their values. It does this by adding the values on the TextChanged event.
The problem:
TextChanged only fires when the text has actually changed (obviously), and not when it has been assigned a new value.
What I need:
A way to detect if the Text field of label has been updated (assigned to), and all I have to work with is a reference to the Control (ie the Label).
I realize TextChanged wasn't designed for this, which is why I'm wondering if any of you guys have encountered a similar problem, and found a solution to it.
The reason that your TextChanged event handler is not invoked in initial assignment of the text is that it is attached after the first text has been assigned (the designer seems to do things in this order by default). I would do like this:
TextChanged calls another method (UpdateGraph)
UpdateGraph collects necessary data and updates the graph
Call UpdateGraph as the last thing done when loading the form
That will make sure that the graph is updated with the initial values. It is important that this call happens after the call to InitializeComponent.
It is fairly common practice in "setters" to ignore trivial changes, for example:
public int Foo {
get {return foo;}
set {
if(foo != value) {
foo = value;
OnFooChanged();
}
}
}
If Text is behaving like this, and you are relying on all updates causing an event, then it may not work as you want. I would probably try to find another way to do what you want; perhaps using an intermediate object that passes the values through.
You could create your own control that inherits from that control and create your own Text property that will fire an event when assigned a new value.

In C# (winforms) how to synchronize a textbox and datagridview so changes in one show up in the other

No database involved here, I am creating my own datatable in code, and binding it to a textbox and a datagridview.
When I change current record in the grid the textbox updates to the current value.
But what's the best way to synchronise changes between the values in the textbox and the datagrid. If I change one then it doesn't change the other unless I go to another record and back.
I can do this by adding a datagrid.Refresh() to the textbox Validated event, and presumably something to the CellValidated event on the datagrid, but it seems like I might be going about this the wrong way.
Edit:
Based on the answer below, my question should be: is there a way to notify bound controls of changes in a DataTable they are bound to, or must the code use a BindingList or do it manually instead.
I suggest you use a BindingList<T> rather than a DataTable, where T is your "business object" that represents each record displayed in the grid. Then your business object should implement INotifyPropertyChanged and fire NotifyPropertyChanged whenever the value in the text box changes, either by binding the desired property to TextBox.Text or updating the appropriate property of the selected business object whenever TextBox.TextChanged fires.

Categories