For the record: I found a similar question here but I have to elaborate a bit more on on the subject.
My concrete scenario is this:
In Silverlight 4, The myFrameworkElement.FindName("otherElementName")
method seems to work fine now, but I encountered a problem. It still returns null
when the element is not yet added to the visual tree obviously.
But now I need this functionality in a DependencyProperty
's PropertyChangedCallback
of a custom UserControl
handler. In this scope, it is uncertain if the UserControl is added to the visual tree yet. But I must execute a certain action on another element in the tree. When the element is already available, it can and should be done right now. If not, it must be done immediately when it is available. So I came up with this extension method that I can call like this:
myFrameworkElement.FindNameEnsured("otherElementName",
result => this.DoSomethingWith(result));
The code for the extension method goes like this:
static public void FindNameEnsured(this FrameworkElement self,
string name, Action<object> resultAction)
{
if (self != null && resultAction != null)
{
object result = self.FindName(name);
if (result != null)
{
resultAction(result);
}
else
{
RoutedEventHandler handler = null;
handler = (sender, e) =>
{
result = self.FindName(name);
resultAction(result);
self.Loaded -= handler;
};
self.Loaded += handler;
}
}
As you can see, I must use an anonymous delegate because I need the values for name
and resultAction
inside of the handler. I then go unsubscribe the event inside of the handler because I'm a smart and clean guy and want no leakage. I also don't want to break any flies on wheels here with some fancy WeakEventFactories or similar stuff.
Now this works smoothly so far. But I have some questions.
- Is this generally a clean enough approach to unsubscribe the event handler inside of the handler? Or is that going to kill an innocent puppy eventually?
- Could there be some issues like some leakage because of using outer scope variables inside the anonymous delegate?
- Can there be thread synchronization issues which would cause me to "miss" the
Loaded
event? In this special scenario, only the Silverlight's UI dispatcher thread should be involved. But if it's a problem anyway, and/or if I need a similar functionality in a non-UI related scenario, what's the best approach to f1x0r it?
Thanks already for your patience and time reading my lengthy elaborations. ;-)