C# - Change child when parent changes - c#

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.

Related

Validating Attached Property in Property Change handler

I am developing a custom control for Windows Phone 8, which is derived from ItemsControl, will have many child objects(another custom class). It needs to have an Attached Property IsMinonAxis which should be set only once by one of the child, and not more than once. So the below code will be a problem I want to avoid.
<WPGraphControl:GraphControl>
<WPGraphControl:GraphLine GraphDataPoints="{Binding SpeedPoints}" WPGraphControl:GraphControl.IsMinonAxis="True" />
<WPGraphControl:GraphLine GraphDataPoints="{Binding AltitudePoints}" WPGraphControl:GraphControl.IsMinonAxis="True" />
</WPGraphControl:GraphControl>
The problem is attached properties are attached to child controls, and not to the parent.
In the PropertyCHangedCallback (registered as part of RegisterAttached as part of PropertyMetadata) I can get the child object for which the property is being set, but I can't access the actual control instance (this) to be able to validate the whole collection of child controls as its a static method common across all instances .
One option I am thinking is to have another attached property (internal) which will be attached when the child controls are added, and then use that property to get to parent inside the callback, and fire the validation logic. It sounds like a overly complicated logic to me.
Could you please suggest what is the best way to handle situations like this?
Might be easier to have a non-attached property on GraphControl that takes a Element to be used. Its been a while since I did WinPhone XAML, but in WPF this would look something like:
<wpgc:GraphControl MinorAxis="{Binding ElementName=Foo}">
<wpgc:GraphLine x:Name="Foo" />
<wpgc:GraphLine x:Name="Bar" />
</wpgc:GraphControl>
Since you can only assign a single value to the property, then this would ensure that only one is set.

Trace AttachedProperty changes from code

I have a custom Control with dependency property attached by its parent and i need to implement some hook that will be triggered on all attached property changes. In WPF it was rather easy but i have no idea how this can be achieved in WinRT environment.
For example, i have Control with attached property X and its parent is GraphArea. So attached property for Control is GraphArea.X.
Please give me some clues, thanks :)
Found the way to do this though not exactly as i wanted to. Instead of hooking to X change inside every Control i've hooked to attached property changed callback of the parent.
Additionaly, i've implemented new interface for all children that must receive notification when this property changes. And as i've implemented interface methods as explicit interface implementations they are not be visible from derived classes (which is good as this operation must be internal).
Another solution is to make code-behind binding between dependency property and attached property and define OnChanged callback for DP. But in WinRT this approach only works for internal Attached Properties (not the custom created).

Dependency properties with sub properties update master property?

I am trying to come up with a solution for the following problem:
I have a DateTimeRange class which contains 3 properties:
Start: DateTime
End: DateTime
Length: Length (=End-Start)
This class is used throughout my project as dependency property on various controls. This values are mutable, for example, if the Start changes, the End will be moved with the same offset (keeping the same Length).
My problem is that in code that listens for updates of the range, does not recieve an event when any of the properties have changed, only when the complete object is replaced.
I want to let the DateTimeRange class notify the user that the whole object has changed when a property is changed, not just one property.
I have tried to make DateTimeRange an immutable struct. But this makes two way DataBinding to any of it's properties impossible.
Does anybody have a suggestion how to do this? IMO this problem is very frustrating, as the same problem happens with Margins for example (you cannot bind to Margin.Left of a control).
The framework does not really support this requirement. The approach I would take would be to make DateTimeRange implement INotifyPropertyChanged, raising the event whenever any of its properties change. On a class that has DateTimeRange as a dependency property add / remove handlers for the INotifyPropertyChanged as the property changes. Within your handler for this event you can then perform the action you require.
Note, you could make DateTimeRange a DependencyObject, which would allow you to create two way bindings to its properties.

WPF Event to capture newly added controls?

We use the ContentControl and other containers stuff in WPF. I need the notification with the new child control is added to the container. What is the best way to get the newly created control within parent?
The ContentControl only contains a single child which is attached via the ContentControl.Content property. You can hook the ContentControl.OnContentChanged to discover when the value of this property is updated.
The cleanest way is to derive from those control and override the methods that report the changes you are interested in. For example derive from ContentControl and implement OnContentChanged. This approach may not appeal to you.
If you want to detect changes in the child or children of controls without deriving from them, you can observe that such changes will affect the layout and so you can hook the LayoutUpdated event. The problem with this approach is that you need to keep track of the children that were previously added yourself by inspecting Child or Children looking for changes. You also have to be careful not to hang onto references to former children lest you create a memory leak. But it can be done.

Object synchronization with GUI Controls

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.

Categories

Resources