Navigating to same viewmodel but with different data and keep navigation stack correct with MVVM Light

Long title, I know… and even with that the scenario I’m trying to describe isn’t clear yet, so let me explain even more.

In my latest app ConcertWall you can open a Venue and look at the concerts that are available, when you open up a Concert you can – again – go through to the same Venue and pick another Concert to get the details.

Now translated to the technical MVVM background this means: Venue viewmodel A > Concert viewmodel A > Venue viewmodel A > Concert viewmodel B > etc…

But when you try to do this in a normal MVVM Light way, you’ll break the Navigation stack! Because when you’ll navigate back from concert viewmodel B to the venue viewmodel A to the concert viewmodel A, you’ll notice A will no longer be visible but you’ll get B again!

This problem is easy to explain, you only retain one instance of the concert viewmodel and if you do nothing when navigating, only the last loaded datacontext will be shown each time you get on the concert view!

Now how can we fix this, there are several ways ( like Nico Vermeir shows one here ), but I like to use the SimpleIoc functionality that is present in MVVM Light and let it handle my instances instead of adding extra in memory containers!

So how do you get this working, first you’ll need to add a special method inside your ViewModelLocator called GetViewModel<T>

This is actually the real solution, all it does is keep track of all separate instances of a given viewmodel based on a key you provide! So no hassle with keeping track of it myself.

Only thing left to do is using this method when navigating to the viewmodel you want to track based on a key ( in our example the Concert viewmodel ).

Best thing to use as key, is the unique identifier that is present in your data model that needs to be shown on that view ( in our example the Concert ID ) and add that to the navigation URI.

Now when you navigate to the view, you can no longer use the MVVM Light datacontext binding in XAML! This because we’ll need to set it our self through use of the above provided GetViewModel method based on the key that is used in the navigation URI. So in the code behind of the given view, override the OnNavigatedTo method and inject the correct viewmodel datacontext!

I’m also calling a RefreshLayout method to refresh the current data on each view load, but depending on the app scenario this is maybe not needed.

With all that in place, you can go forward and call the same viewmodel with different data over and over, and keep your navigation back stack intact because of the added key inside the navigation URI.

Happy coding!

Picture library image control for Windows 8 store apps

So on a recent Windows 8 store app project, we wanted to let the user pick images from his hard drive to use them inside the app.

But with Windows 8 store apps we are a bit restricted on rights to get a hold on files anywhere on the pc’s hard drive. Sure when you select the file you can read it, but when the app restarts that location could be no longer available to the app itself due to rights restrictions.

So, how could we solve this? We could store the images binary inside some sort of database… but for our app that would be a bit too much. Other solution is just using the default Picture library that is available on the pc itself!
It’s easy to give the app rights to this folder… it’s right there in the Capabilities section all you have to do is switch it on!

image

With that in place we only needed to create an image control that would allow us to use a normal string, representing the path to the location of the image, as source. But the control should also let the user select images and copy those over to the picture library so we can reuse them later!

So let me introduce to you the PictureLibraryImage control!
It’s a user control that contains an Image and has some extra Dependency Properties.

The xaml looks like this – note there are 2 fading animations, they are used to let the Placeholder image fade out and the Source image fade in, after it has been loaded!

The properties we are introducing are:

  • Placeholder : we use this to show a dummy image when there has no source been set yet
  • Source : the path to an image inside the picture library
  • FolderName : the name for the folder we use to put the user selected images

When you place the control in your app and run the app, you can tap on it to get a hold of a FilePicker, this will let the user choose an image! When an image is chosen we copy it over to the given FolderName location inside the Picture library… the code looks like this:

Now comes the last part of our control! We have to be able to use a string pointing to a file inside the picture library as source…

This is actually very easy with the Source dependency property in place and the Picture Library capability. We only have to read out the file and set it as BitmapImage to the image ssource inside the control! The code for this is

Only thing left to do is use it in your project… the source can be binded to some MVVM property of course.


Let me get one thing straight, this is not by any chance the most elegant solution… but for our needs it served the purpose very well.

Just go through the code, maybe there are other things you could reuse instead of the actual control itself 🙂

Everything is up on my Github here… so download, use and any suggestions or improvements are welcome!

Twitterate your Windows Phone app

Thanks Scott for helping with the Path control!

Well, the people of twitter have streamlined the look and feel of their mobile apps, so that it almost looks the same on each platform.
Currently on Windows Phone this means it’s like this:

twittermain

So you will see a set of icons on top with a content body below and by selecting one of the images you will switch the content body.

But the special thing about this, is that the body content will ‘slide’ from one to another, meaning in Windows Phone development terms this is most likely a Pivot control. Weird thing though, the icons are not inline with the standard Pivot control header. If so they would not be all on the same page. 
How can we mimic this ourselves?

I have no doubt there would be several different possibilities, but let me give you mine…

Create a new windows phone app and in the MainPage.xaml add a ListBox called ImageBar.
This imagebar will host our 4 icons!
Each icon is represented with a custom Path control that contains XAML data ( more on this below ). To get nice looking icons, just download Metro Studio from Syncfusion! Open the program, look up a nice icon and copy paste the generated XAML data. The listbox XAML will be:

After this, also add a Pivot to the page, but don’t add a HeaderTemplate ( we don’t need one ). The one in our solution looks like this:

Now there are several things going on in here! You will see that both the listbox has a SelectedIndex bound to that of the Pivot in two way mode, these are needed to keep the image listbox and the pivot in sync on what is selected.

Now when you would run this, nothing will happen with your headers, because we need to give the selected icon a colour when it’s selected. This is done by giving the listbox a custom ItemContainerStyle in there we are going to use the visual states of the listbox to set the colour when an item is selected! In our example we the PhoneAccentColor for the selected state and PhoneInactiveColor for the unselected state…

For this trick to work we needed to create our custom Path Control! Because using a Style Template will try to set/change the ForeGround of a ContentControl, but a default Path control only has a Fill property! The custom control will use template binding to take the ForeGround value and use this as the Fill value. We do the same for the Content itself, this is used for the Data property of the Path control.

Do note in this style, we also set the HorizontalContentAlignment to Center so each icon takes center place in the list item…

But still, when you would run this, each icon will stick to the next! So how do we divide them evenly. You could calculate this and add margins or change something else… But in our example we again use a special control derived from Panel, called SplitPanel and use this as ItemsPanelTemplate on the listbox.

This control will calculate the total amount of space available and evenly change the width of each item to match this.

So when all is done, you should get following result: ( source code is up on my GitHub here… )

PivotWithIconHeaders

Fixing header when scrolling content on windows phone page

Thanks to Kévin Gosse @KooKiz for tweaking a part of the code to get it right 🙂

So, sometimes you want to try something different on Windows Phone and this time I wanted to tweak the scroll animation of a page.

The setup I was looking for visually: You have a content page ( for example in a news app ) that shows a nice article with an image and a title caption on top. But as you can see the text of the article is too large, so when the user scrolls down to view the text, we want to keep the header title in view! ( or something else depending on your taste )

TextPage TextPage2 TextPage3

You would think this would be easy, but it alas! Again we are faced with a stripped down XAML version in Windows Phone, so we don’t have the same ‘control’ over these events as in WPF.
Now with some small tricks, it’s possible to get a decent working version, so let’s get to it!

Just create a new Windows Phone app in Visual Studio, when doing so you’ll get a MainPage.xaml right away.

We are going to change the page, so delete everything inside the LayoutRoot grid and replace it with following xaml


If you did this correctly ( also there should be a bear.jpg image inside the Assets/Images folder 😉 ) you’ll get a nice page representing the article!

TextPage

You’ll notice the page has a scrollviewer that contains everything except the header title! The trick we are going to use, is manipulating the location of the header title ourselves.

Do note that we need to se the ManipulationMode of the ScrollViewer to Control to get a smooth UI effect! ( see xaml above ) Otherwise the UI won’t be notified enough with the scrollviewer scroll values – is a performance optimization that we now need to bypass.

To manipulate the location of the header title, we need to keep track of the scroll offset of our scrollbar. But the scrollviewer itself doesn’t give use enough info, the way to get this info is by hooking into the ValueChanged event of the VerticalScrollBar that is inside the ScrollViewer !

So first we need to get hold of this VerticalScrollBar, this is done by using the VisualTreeHelper on our ScrollViewer and hook onto the ValueChanged event.


Inside our ValueChangedHandler we will animate our header title to the corresponding vertical offset of our ScrollBar, but we will stop animating when the vertical offset is higher than the top position of our header title when the page was launched!! Because if our vertical offset has reached that value this means that the header title will be positioned at the top of our page!

The top value of the header title is called _borderTop and is calculated at page load.


With that in place all is looking great, except for one thing: what to do when the user compresses the ScrollViewer by dragging the content down when the page is at it’s initial position. This behaviour is sometimes used in listboxes to get that ‘pull to refresh effect’. When someone does this on our page, the header title will stay at it’s position while the rest is dragged down… not a nice effect indeed. Let’s fix this.

This can be solved by hooking into 2 other events of the ScrollViewer: MouseMove and MouseLeftButtonUp. MouseMove to detect the compression and MouseLeftButtonUp to know when the user stops the compression.

When the compression occurs, you’ll notice a positive TranslateY value on the CompositeTransform of the ScrollViewer content, we’ll use this to also animate our header title. When the compression is stopper, we check if we had a positive TranslateY value and if so, we reset the position of the header title.


If all goes well, the end result should look like this

 

To not mis anything, the demo project is up on my github here https://github.com/Depechie/FixedTextScrollDemo

Facebook like settings pane with gestures – windows phone

In my last post I showed you how to mimic the settings pane used in the Facebook app on windows phone through use of Visual States ( read it here… ).
But that solution was not 100% the same as in the Facebook app, it missed drag gestures.

So, let’s add those 🙂

First you’ll need to add the Windows Phone Toolkit nuget ( http://phone.codeplex.com/ )! Because it has a GestureListener, that you can hook up in XAML to almost any control. It will give you events for all possible windows phone gestures.


You’ll notice that with this, we are hooking into the DragDelta and DragCompleted events. We are going to use these events to animate our page.

In the OnDragDelta event we will check to see if there has been a Horizontal gesture detected and if so, depending on what pane is already open, show the animation on screen! Take a look at the code below and you’ll notice some tricks to get this done! Basically we calculate how far the user is dragging the content and if he get’s passed DragDistanceToOpen ( or ToClose ), we will start the rest of the animation.

If the user stops the drag gesture before reaching the given distance variable, we animate the screen to the given distance… ( through use of the SetHorizontalOffset method )