1

In one of my applications I need to allow the user to customize the user interface in certain ways. To do so, I'm allowing the user to specify the user interface in XAML, which I load dynamically when the application is started. This works fine.

Now I want to provide custom control to the user, which is derived from Border (let's call it MyFrame).

I need to make sure that MyFrame may not be child of another MyFrame, so the following should be prevented:

<ns:MyFrame>
    <Grid>
        <ns:MyFrame />
    </Grid>
</ns:MyFrame>

How should I implement this?

Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139

2 Answers2

3

You won't be able to do this at compile time.

However, at runtime, you can check whenever a new instance of MyFrame is created, if it has a parent MyFrame, using this visual tree walker. If it does, raise an exception.

Community
  • 1
  • 1
Louis Kottmann
  • 16,268
  • 4
  • 64
  • 88
  • it's not *always* work (in my exp. +-70% of cases), but it's absolutely valid option to try. – Tigran Jan 16 '12 at 13:46
  • 1
    What do you mean when saying it doesn't *always* work? Of course, I want a solution that works in 100% of the cases. Otherwise I might save time and not implement it... – Thorsten Dittmar Jan 16 '12 at 13:54
  • 1
    Actually, Tigran probably had trouble using the methods provided in the link i gave, because you have to be careful with XAML instantiation order: if you try to find something that gets instantiated after you check, you might find nothing whereas there should be something. Keep this in mind, and it's a 100% solution =) – Louis Kottmann Jan 16 '12 at 14:02
  • I've used the `TryFindParent` method from the link you provided and am calling it in `MyFrame`'s `OnVisualParentChanged` method. Thus, I'm checking for the existence of a parent when the child is (re)assigned to a parent. In that case I suppose that both are created and this should work. – Thorsten Dittmar Jan 16 '12 at 14:21
1

I would throw an exception with a clear message from the Loaded event handler on MyFrame: step through the ancestors of the new MyFrame instance and try to find another one; if you do find one, throw the exception.

Alternative: use an inheritable attached property that you set on all instances of MyFrame - and check that in the Loaded handler.

I can't imagine any way to enforce your rule in a static manner.

Csaba Fabian
  • 846
  • 9
  • 19