I’ve been exploring the Windows Phone 7 SDK in preparation for a launch event in New York next week by porting the CodeStock Android application to WP7 and I’ve run into a bit of a headscratcher.
The Android app uses a context menu option to permit the user to refresh the data from the website “on-demand” so I created an ApplicationBarIconButton (named “downloadScheduleButton” surprisingly enough) for the same functionality. On first test the app crashed with a null object reference on the line in the main page’s constructor added to wire-up the click handler. The line of code looks like this:
this.downloadScheduleButton.Click += new EventHandler(downloadScheduleButton_Click);
The null reference was “downloadScheduleButton” and yes, I did put the line after the call to InitializeComponent(). The generated SilverLight code for the page included this line in InitializeComponent:
this.downloadScheduleButton = ((Microsoft.Phone.Shell.ApplicationBarIconButton)(this
.FindName("downloadScheduleButton")));
but FindName was returning null. The docs for FindName included this note:
"A run-time API such as FindName is working against an object tree. These objects are loaded into the content area and the CLR runtime engine of the overall Silverlight plug-in. When part of the object tree is created from templates or run-time loaded XAML, a XAML namescope is typically not contiguous with the entirety of that object tree. The result is that there might be a named object in the object tree that a given FindName call cannot find."
The docs continue by discussing using GetTemplateChild, VisualTreeHelper, or XamlReader.Load but none of the cases seem to apply here. Further, the ApplicationBarIconButton class doesn’t expose a Name property so I can’t write my own method to loop through buttons and matching by name.
I got around it by using
((ApplicationBarIconButton)this.ApplicationBar.Buttons[0]).Click += new
EventHandler(downloadScheduleButton_Click);
but that’s awfully fragile and will break if the order of buttons is rearranged. What am I missing here?
No tags
You can look at: http://blogs.msdn.com/b/ptorr/archive/2010/06/18/why-are-the-applicationbar-objects-not-frameworkelements.aspx
“… Firstly, the ApplicationBar is not a Silverlight element and thus not all Silverlight concepts apply to it. For example, you would expect that the Background could be set to any kind of brush – SolidColorBrush, LinearGradientBrush, and so on – but because the AppBar is actually rendered by the Windows Phone shell, it only supports a solid colour. You might also expect to be able to put arbitrary Content inside the buttons, or to apply RenderTransforms to the menu items, and so on. And you should be able to put it anywhere on the screen with HorizontalAlignment / VerticalAlignment, right? Again, none of these things are supported by the underlying shell UX, so they would all have to throw exceptions or no-op when called. And where’s the fun in that? …”