Every time when I change some values in form controls, I need to set a property of an object or vice versa. Instead of writing some methods for each control, I want a general solution for GUI elements. I do not use WPF but only C# 3.0.
Any suggestions?
Thanks.
All controls expose events that signal that their value changed. You can subscribe to it and change another control's value.
You could make the object a field in your form. When the relevant event fires from a control, then call the appropriate operation on the object.
Alternatively, have a Presenter/Controller object that stores your form as a field. It could take it as a parameter in it's constructor. This presenter can then subscribe to your form's relevant events and act appropriately. You could go further with this and extract an interface from your form and program to that in the presenter instead which would help testing. Have a look at the MVP pattern.
Related
I am doing an app in C#, Windows Forms.
In this app I have a main form that has several Elements in it. This "Element" class is inherited by others ("ElementLabel","ElementPicture","ElementGraph").
At some point i might want to change in "batch" mode some property of several elements, whichever they are. For example, I might want to change the property "Value" of all the selected elements.
The problem is, for example, when the property "Value" is changed in the parent class, I also want to change the property "Text" of a "Label" that exists in the child class "ElementLabel". I've seen a lot of topics on changing the parent through the child, but not otherwise.
Am I missing something here or do I just have a bad design and a situation like this isn't even supposed to happen?
Thanks in advance
Well its hard to say what the best option is without knowing more about your architecture, but subclasses can intercept events in the parent class by overriding methods. For example, in your ElementLabel class:
public override void set(String key, object newValue) {
if (key.Equals("Value"))
set("Text", "New label text!");
base.set(key, newValue);
}
If you want a more general solution, you could include an observer pattern in your parent class; see the wikipedia page
You could use for the data a class (or classes) that implements INotifyPropertyChanged.
Then you would have to pass to the child controls references to a "master" property that you used to control the state. (It would be ideally used by a Controller class.) (I'll refer to this object as the "master property object".)
Each of the child controls would subscribe to the PropertyChanged event.
Then when the Controller changes the value of one of the master property object's properties, it will raise the PropertyChanged event, and each interested child can respond appropriately.
This approach helps to decouple the controller from the views.
The sequence is:
Before creating the child controls, create the master property object. Keep a reference to this in the Controller or Main Form (if you're using that as a controller).
Pass to each child control that needs it, a reference to the master property object.
Each child control should subscribe to the master property object's PropertyChanged event.
Write an appropriate handler for each child. It will have access to a reference to the master property object, so it will be able to see the new values of any properties.
When a property needs to be changed, the Controller simply sets the property as desired. The property setter implementation should raise the PropertyChanged event, and that will notify all the interested child controls, who will update their UI in response.
[EDIT] This is in fact an implementation of the Observer pattern that Reyan mentioned above.
I'm new to c# and I'm looking for a way to bind a property of an object of my own to the value of a textbox in a regular form (reset the property of the object everytime the value of the input changes).
I have read some information and it seems that this can be done only for database objects. Can you give me additional information.
Assuming you mean Windows Forms textbox,
say
textBox.DataBindings.Add("Text", obj, "SomeProperty");
whenever you feel like binding it. Bindings are usually done in Form_Load event handler, if the object can be obtained at that time of course, and if there's no complex logic with different data sources.
Note that this will only work in one direction (changing TextBox will yield object property changes). To sync the other way round, the object must implement INotifyPropertyChanged interface.
If you want to persist the information between runs of the application (i.e. have it be saved when you close the app and re-appear when it opens), it's easiest to use the Windows Forms designer (I assume you are coding a WinForms app) to bind the value of the TextBox to an application setting. (This article on validation provides a screenshot similar to what you want.) (EDIT: Here is the exceptional article on the subject: Exploring Secrets of Persistent Application Settings. And here is a snippet page that I put together to discuss binding.)
This binding is automatically two-way, unlike the binding that #gaearon mentions. You just need to make sure that you save the settings (i.e. Properties.Settings.Default.Save()) before closing the application (e.g. as the event handler for the Form.Closing event).
If you need more clarification, leave a comment.
C# How do I use an even to get my GUI update on change of an object?
I have a GUI program that creates an object and displays the object in a data grid through reflection.
When the user updates the information I want to be able to verify the new information and send feedback to the user. I have a method that does the verification of the information, I just need to figure out how to update the GUI with the new information.
thx.
Another general approach would be to support IObservable on your object, and IObserver on any classes (such as user interface elements) that wish to be notified of changes to your object. You can have any number of observers of changes on your object. It's a little more work than the "out of the box" data binding on controls such as data grids, but I would say more flexible.
Perhaps you could be more specific or show some code, but check that each Column Object of the .Net Datagrid has a property named DataPropertyName, which binds by reflection to the property of your objects, it should work..
Other thing is to implement the INotifyPropertyChanged on your objects, and Refresh the Grid on the PropertyChanged event.
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 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.