Jan 28, 2011 at 1:51 AM
Edited Jan 29, 2011 at 12:38 AM
I was too quick answering. Indeed the issue is there, but it was not the one I was expecting, since in the first post you stated that the parameter was null... while I was getting a proper value.
The last post, where you cleanly state the issue, has indeed helped me a lot to understand what's going on. :)
And to add something nice to the news, I found what is the problem. :)
The fact is that your visual tree has multiple objects with the same name and the extension function used to retrieve the named objects (ExtensionsMethods.GetNamedElementsInScope), traverses the tree top-down.
To be fair, the function will drill-up the tree until it finds either a named element scope (setted by the
Bind.Model), a UserControl (that is considered the closure of a named scope) or a tree root (having a
null parent), and than starts returning the children in a breadth-first way.
Unfortunally the SearchTextBox does not meet either of the above criteria, so the search is performed up to the root tree every time (3 times).
To be clearer consider the following schema as a representation of your visual tree:
|_ SearchTextBox (ActionPointsFilterTextBox) [A]
|_ SearchTextBox (ActionPointsFilterTextBox) [B]
|_ SearchTextBox (ActionPointsFilterTextBox) [C]
(bear with me for the poor ASCII art --')
As you can imagine, this is what's occurring:
- When ExtensionsMethods.GetNamedElementsInScope is called on [A], just one element with the required name is returned
- When it is called on [B], two are returned
- When it is called on [C], all of them are returned
Now, since the named element is the first having the specified name (because of the search performed by
ExtensionMethods.FindName), your parameters are always bound to the first
There are some ways to fix this:
- Return the last element in the collection of named objects matching the criteria instead of using
- Traverse the visual tree bottom-up, so that the nearest named element is always found first (the effect is exactly the obove one, but you can implement this strategy replacing
ExtensionMethods.GetNamedElementsInScope and is probably the best solution for the CM framework too, since I suppose is the same strategy used by the framework name resolution... well, simplified)
- Mark every SearchTextBox as a named element scope setting the View.IsScopeRootProperty to true (either by code or modifying source to add getter and setter, otherwise the compiler complains)
- Determine the realization of a DataTemplate as a name scope (not a good idea, since named object outside templates would not be found)
I suppose that solution 2 is the way to go, both to avoid the issue in your code, and as a proposed fix for the CM framework.
@Rob: I hope I avoided you some headaches!
I edited my proposed solution, since I figured out that I was thinking in a too simplicistic way.
The fact is that the search should be probably performed on a nearest-neighbour basis (i.e. count the distance of each named element from the start point and sort the list accordingly). Maybe it could be worth to check the algorithm that WPF/Silverlight
use internally, to try to match the deafult naming resolution strategy.
@Rob: Maybe I gave you even MORE headaches!