Validating Attached Property in Property Change handler - c#

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.

Related

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).

Using Dependency Properties on multiple user control instances

I created a user control that have multiple dependency properties that work correctly. My problem is that when I create multiple user control instances and bind the same DP on the same external property and I modify the second instance of the User Control the input for the first instance will be also modified and I don't want that. Is there something like a x:Shared property for DP's that will keep each DP with his instance?
I don't think this question needs code attached because is somehow a general question.
Regards

C# - Change child when parent changes

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.

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.

How is the Parent property of a FrameworkElement set in Silverlight?

I have written a custom Silverlight control based on Control. I have two DependencyProperties called Top and Bottom which both hold child controls for a specific layout display. I then use a ControlTemplate to arrange these two controls into a grid, placing one on the 0 row and the other on the 1 row. The problem I have is that I cannot seem to figure out how to get each child control's Parent property to point to my custom control. When I inspect each control at run-time, the Parent property of each is null.
This is a simple example, but I think you can see the general problem. I have a number of more complex controls that all share this problem. I know there is some magic I am missing. If a ContentControl's Content property is set to some child it is somehow setting that child's parent to itself.
Edit: A little more info
In WPF, one might use functions like AddVisualChild(), RemoveVisualChild(), AddLogicalChild(), RemoveLogicChild() to manage parent/child relationships, but these functions are not available in Silverlight.
After quite a bit of research I believe that this is not possible. I was able to recurse through the Visual Tree instead of the Logic Tree using the VisualTreeHelper to accomplish my ultimate goal.
The Parent property cannot be arbitrary, it reflects the real parent of the control for use when rendering.
From MSDN:
Parent may be a null reference (Nothing in Visual Basic) in cases where an element was instantiated, but is not attached to any logical tree that eventually connects to the page level root element, or the application object.
...
Changing an element's parent is typically only done through manipulation of collections, by using dedicated add or remove methods, or through setting content properties of elements.

Categories

Resources