Bindable links & Selected items

Aug 7, 2014 at 2:03 PM
Edited Aug 7, 2014 at 2:04 PM
I'm trying to do a project using the Modern UI, and while I LOVE the look and the features there is one thing that is really holding me back: I can't bind my menu items / links to a collection, and then capture/bind the selected item in that collection (like a normal list box or tab control).

I have dynamically generated menu items. It was easy enough to bind the ModernTab.Links to a LinkCollection on my view model, however the selected link escapes me. Since everything is dynamically generated data objects, the "Source" page for every link is the same, just the display name is different. The selectedsource property only looks at the source uri, which is the same for every link. It seems as though this has been built for a static page-navigation type application as opposed to a data driven one. It would have been nice if ModernTab inherited from the TabControl, instead of just Control so you get your Items, ItemsSource, SeletedItem, SelectedIndex, etc.

Every way I try to skin the ModernUI cat it only cares about the source uri, which again is the same user control for every link in the moderntab; just different data to fill it in.

Is there a solution for a more dynamic data-driven application using Modern UI?
Aug 7, 2014 at 2:33 PM
So my last idea was to capture the left mouse button up event on the modern tab. If the MouseButtonEventArgs.OriginalSource is a textblock or a Border (same button, but outside the range of the text), I can capture the text of the link then pass it on to the view model and lookup the correct data object. This is super hack-ish, but works for now. Would be nice to have a cleaner solution, even to just bind the selected link to an object on the view model (not just the source uri)
Coordinator
Aug 9, 2014 at 5:09 PM
You should make sure the Source is unique for each Link. The whole selection mechanism depends on it. Possibly use # or ? to distinguish between links
Aug 11, 2014 at 12:17 PM
But that's the point I'm making: in a data driven application, I have a list of items for my modern tab items, and the selected item's details I want to show in the page area. So, the page is the same user control for every item just filled in with different data from the selected item. It would be redundant to make 10 pages with the exact same code, just named different. Plus, the list of items is dynamic and the number of items in the tab will change over time.
Or perhaps I'm thinking of it the wrong way? Can I pass parameters using your link methodology? So say the source link is "/pages/pagename.xaml?id=1", could I pick up url parameters on the page and then load the data object passed?
Coordinator
Aug 11, 2014 at 1:40 PM
Edited Aug 11, 2014 at 1:41 PM
Exactly, you can use the anchor tag (#) to create unique sources. Additionally when you implement the FirstFloor.ModernUI.Windows.IContent interface, you can read the uri fragment part in your content. When fragment navigation is performed, the control is not reloaded.

Consider the following list:
<mui:ModernTab Layout="List" SelectedSource="/Pages/MyPage.xaml#1">
  <mui:ModernTab.Links>
    <mui:Link DisplayName="Item 1" Source="/Pages/MyPage.xaml#1" />
    <mui:Link DisplayName="Item 2" Source="/Pages/MyPage.xaml#2" />
    <mui:Link DisplayName="Item 3" Source="/Pages/MyPage.xaml#2" />
  </mui:ModernTab.Links>
</mui:ModernTab>
And MyPage.xaml.cs
using FirstFloor.ModernUI.Windows;

public partial class MyPage: UserControl, IContent
{
  public void OnFragmentNavigation(FragmentNavigationEventArgs e)
  {
    // TODO: handle fragment
    var fragment = e.Fragment;
  }

  public void OnNavigatedFrom(NavigationEventArgs e)
  {
  }

  public void OnNavigatedTo(NavigationEventArgs e)
  {
  }

  public void OnNavigatingFrom(NavigatingCancelEventArgs e)
  {
  }
}
Now every time a link is selected in the ModernTab, MyPage.OnFragmentNavigation is invoked with the fragment info of the selected link source.

More details in Handle navigation events in your content. Also the ModernUIDemoApp (in the source, and included in the download) contains a ModernFrame sample demonstrating this behavior.