In my project I have a settings form. Where if any changes happen I have to notify user about it if he wants to leave that page without saving his changes. At this time I am doing this by catching every control change event. I am sure there is a better way - like catching the change event from its container. Is it possible?
Rather than worrying about the controls directly, how about creating a Settings class that implements interfaces from System.ComponentModel like INotifyPropertyChanged and IDataErrorInfo and use data binding to get the values in and out of the controls.
Your Settings class can then not only record whether anything has changed but also make validation of the user input easier.
A good place to start is MSDN.
You have the right solution, but you may want to be very generic about catching the change events. For example, you could try something like this right after the InitializeComponent(); line in the constructor:
foreach(Control c in Controls) {
c.TextChanged += new EventHandler(genericTextBox_TextChanged);
}
genericTextBox_TextChanged would set a form-wide hasChanged flag to true, or something really basic like that. You may need to make this into a recursive function that loops through all of the children of c if it has child controls.
Let me offer you some kind of a workaround. My offer is to create a custom DataSet. Then add tables corresponding to the form controls. After this you can bind each form control to this dataset.Pros: You keep all the controls data-bound. So you don't need to care about the changing of particular control. You have just to control dataset changes. Cons (maybe): after this you should rewrite settings preview mechanism. Instead of changing controls you have to change data. IMO, it's not so hard, but I have no idea about this approach in your applicationI think this approach will be, at least, easy to debug.
If it's web, look at the unload event for javascript
Related
I have created two separate UserControls and (depending on which RadioButton is selected) I would like one or the other to be displayed.
Right now, I simply dragged one instance of each UserControl onto the form and placed one on top of another (setting one .Visible = false;).
This is OK, but I was wondering if there was a better or more appropriate way to do this?
That's perfectly reasonable.
If you're concerned about keeping around resources you're no longer using, you can add a Panel and add or remove the control from there.
E.g.
try
{
panel.SuspendLayout();
panel.Controls.Remove(userControl1);
panel.Controls.Add(userControl2);
}
finally
{
panel.ResumeLayout();
}
If the user controls do things like connect to data sources, you might want to actually dispose and recreate them. Really depends on how complex the controls are. If they're just capturing a few properties, your current solution is fine.
In my application, different controls are only used dependent of the values of properties from a particular object. The forms constructor accept this object as a parameter.
The form has always some basic functionality, no matter what properties are set of the particular object.
Now I have something like this:
if(myObject.SomeProperty)
{
myControl.Visible = true;
myOtherControl.Visible = false;
// and so on
}
At this time, the controls that are dependant of SomeProperty are buttons and tab items. However, I can imagine that in the future other controls are added to the form and are also dependant of SomeProperty.
As you might guess, I want to set this up the right way. But I don't know exactly how. How would you implement this?
There are multiple ways I can think of solving this, depending on your situation you could select the best suited to you.
1. Databinding is one elegant solution when managing the state (visibilit or other properties) of multiple control's depend on a different object. Additional details in this question
2. You could write different functions if the combination of the states is only limited to couple of cases to at most 4-5 cases. That ways you can still reason about the methods which set the state depending on the object you are depending on. Ex: Basic_Editing, Advaced_Editing, Custom_Editiong etc.
3. If the number of cases are limited you could create multiple forms (User controls) and load them on demand based on the state of the dependent property (or object you are talking about).
Just having a bunch of if else's makes your code harder to maintain, or comprehend, logically group the states so that 1. You could reason about it later, 2.Someone else understands the reason/logic 3.When there is a change required it can be localized to one of these modular methods (techniques) reducing the time to fix, and test.
I would do it like this in form constructor:
myControl.Visible = myObject.SomeProperty && !myObject.SomeOtherProperty;
myOtherControl.Visible = !myObject.SomeProperty;
....
Is it the less code and its rapidly changing.
OR
You can create separate functions that will generate controls dynamically at runtime for each form view based on object properties.
First i can see you are setting visibility on/off it means you have already controls on the form every time.. , so that not a good practice, instead create controls only when needed.
As for your scenario you can have an function like Initialize() which contains all the code for checking if showing a particular control should be shown or not and then create it and add it to Forms control collection. If any new control come to be added later you have one function to update.
A more precise answer can be given if you can provide more detail to you scenario
Sounds a simple question but haven't found a way to do, so would solicit any responses I get.
I have a winform which in turn contains a user control object. based on some condition in the user control, i have to set a value in the winform.
One way could be to pass the winform object as parameter to user control but that would give cyclic dependency. Is there a easy way out?
You can always use events from the user control to the form.
User Control Events in VB and C#
Writing C# Custom Events
Usually I would expose an appropriate event from the usercontrol. The form can subscribe to the event and react accordingly.
I'm making a custom control.
Basically what I'm looking for is a OnPreInit event in custom controls. I basically need to know that all of the controls that will be loaded of type MyCustomControl are constructed or not.
Ok, so basically I need to know in the constructor if the current instance being constructed will be the last.
Note: My custom control contains other controls(though this isn't guaranteed) but it will not contain controls of MyCustomControl class.
I've thought about doing an override of AddParsedObject. But if the instance of my custom control doesn't contain any controls, will this still get called?
Unfortunately the approach you're describing is "non-trivial". That means it might not be technically impossible, but so difficult to do correctly and has so many negatives/downsides that you will be better off stepping back and analyzing the larger problem for a different design. Perhaps if you re-posted articulating the end goal you're trying to accomplish, we can help you find an approach that is viable.
I hate to say use a counter, but you're either going to have to pass state information through a dedicated class (or the context,) which you could do in the constructor of the control prior to testing if you've got as many as you need, or you could do a recursive walk through Page.Controls and their .Controls and test each one for type....
I have a form with several components, like TextBox and ComboBox, and I need to know when click in the out button if there was any changes in the form. Is there a way to do this?
You could create a generic change event handler which sets a flag on change, and then assign all the controls' Change events to it.
This could probably be done pretty easily by looping through all of your controls onload.
You could loop through all controls but this would have to be recursive because a control can contain controls, e.g. (no null checks for brevity):
private void IterateOverControls( Control parent )
{
ProcessControl( parent );
foreach( Control control in parent.Controls )
IterateOverControls( control );
}
In ProcessControl you could hook up event handlers to handle OnEnter (to store the state) and OnLeave (to check the current state against the stored state). You'd need to unhook all the event handlers when disposing. Also, the code to store check the state would have to change for different control types, e.g. TextBox would be the Text property, but a radio button would be an index, etc. Obviously this becomes simpler if you can compare form state to your underlying data store state, in which case you can just make the comparison on each OnLeave event.
One thing also to consider is do you need to track real changes? For example, I have 2 radio buttons: A and B. I check B (a change), so the out button or whatever has its Enabled property changes. I then click on A (i.e. back to my original state). Do you need to revert the button at that point?
This is why you should look towards a model view controller approach :)
The easiest way to do this would be to simply use a variable on the form named something like "IsChanged." Set it false when the form is initially displayed, and set it true if they make any changes.
Alternately, you could record the values of everything when the form is displayed, and when they finish, check the current values against the old ones to see if anything changed.
If this is already nearly finished, and you need something quick it's probably going to be easier to just always assume that something has changed, then in your update logic afterwards (whatever it's doing) don't update stuff that is still the same.
As someone else mentioned, it's very possible for someone to change something, then change it back. What would you want to do in that case? You won't be able to maintain a proper dirty state of the form without a fair bit of additional work.. this is something that you need to plan for before you start, really.