Where were we?
In the last post I described getting started with writing a Windows Store app up until I hit the snag of “how to create a round browse button”.
Lets see how I got on after that!
Actually Creating The Browse Button
After posting a question on StackOverflow, I got an answer:
Seems rather excessive. I was kind of hoping for something like we had with AppBarButton, or at least something like:
But anyway, we have our answer for now (please, if there’s an easier way to do this, add a comment!).
Writing a ViewModel
So lets add a view model - in the shared project, create a ViewModels folder and add StartPageViewModel.cs.
For now, I’ll create a “Name” property in the ViewModel and then create a TextBox in the view, just to make sure that everything is wired up properly.
And
Now, I need to add an attached property to the StartPage to tell Prism to auto-locate a view model for the page:
Ok, let’s implement IView on StartPage. Hmm the error is still there. *quick googling*. So it seems that’s a bug in Prism - fair enough - lets ignore it, it shouldn’t cause a problem.
Time to run the program to see if that worked!
Oh… “The text associated with this error code could not be found.” - that’s helpful! Um… How about we manually implement IView:
Aaaannnnd… That works. WTF? I can’t even imagine what’s going on here. Page obviously implements DataContext so why couldn’t it be bound before? What difference does explicitly implementing the interface make?
Binding the Button to a Command
Anyway, it’s working. Lets skip ahead 5 minutes now, when I find the Command
binding on
my button isn’t calling the ICommand I’ve created for it on the ViewModel. I try changing the
binding from {Binding OpenFileCommand}
to {Binding BadOpenFileCommand}
. BadOpenFileCommand
doesn’t exist, but I want to make sure that binding errors are being displayed in the Output window
as they would in WPF.
Oh, it seems that those messages appear only when the debugging mode is set to “Mixed”. Lets try that.
Now we’re getting somewhere:
Error: BindingExpression path error: 'BadOpenFileCommand' property not found on 'Vera.ViewModels.StartPageViewModel'. BindingExpression: Path='BadOpenFileCommand' DataItem='Vera.ViewModels.StartPageViewModel'; target element is 'Windows.UI.Xaml.Controls.Button' (Name='null'); target property is 'Command' (type 'ICommand')
OH HOLD ON! I’ve forgotten to bind the DataContext property to the strongly typed ViewModel property needed by ReactiveUI (I love ReactiveUI)! My bad.
LESSON LEARNED: Use “Mixed” debugging mode! Maybe this should be the default? Binding error messages are invaluable in debugging.
And Crash
I’ve not changed anything! That worked last time I ran. In fact, it seems to occur every other time I run. And the stacktrace doesn’t tell me much.
Lets try turning off “Mixed” debugging.
It doesn’t crash any more! Aha, so that’s why Mixed debugging isn’t the default!
LESSON LEARNED: Don’t use “Mixed” debugging mode!
The File Picker
Next thing to do was show the file picker. That went pretty smoothly!
Navigate to a new Document
Once the user has selected a file, I need to navigate to a new Page. The NavigationService we used in App.xaml.cs isn’t available in Page as it’s a part of Prism. It seems like the way to do this is by making the page inherit from VisualStateAwarePage.
When this didn’t work, I gave up in frustration and vented on Twitter.
However, it looks like the XAML team have the last laugh. The problem was that I’d mistyped the xml namespace declaration:
xmlns:prism="using Microsoft.Practices.Prism.StoreApps"
Note the space there instead of a “:”. It might be nice if the XAML editor showed errors in using declarations, but this was 100% my fault.
Conclusion
I came to Windows Store apps with high hopes. I’m a relatively common WPF user, and I’m even in the process of writing my own windowing framework Perspex so I understand how difficult this stuff is. But compared to WPF and MahApps.Metro, I was quite shocked at how many roadblocks were placed in front of me.
I wonder how a new developer coming to the XAML stack might find it? Apart from the problem of the bugs, the direction seems to have gone away from streamlining the framework and into adding more boilerplate. Unless of course you’re willing to use something like Prism, but that itself seems to introduce a number of problems. Of course maybe this is my problem - being somewhat of a veteran - and this would all make sense to newcomers.
Maybe if I decide to continue, I will add to this series, but that’s all for now.