Inspired by some great apps out there, I want to have a PanoramaItem
in my Panorama, that is wider than the standard width of the PanoramaItem
.
See the item with tiles in LinkedIn's app:
Normally this is achieved in xaml by adding a PanoramaItem
with a predefined width:
<controls:PanoramaItem Width="555">
But, I would like to avoid hardcoding my UIs this way, as the application is Caliburn-Micro based, and the Panorama control is data-bound using handy Caliburn conventions. The view model behind it is a Conductor, and pages are injected into it. The Panorama
control is bound to the Items
property of the view model.
My problem is that if one of the items, or screens, is wider than the standard width of the panorama item, it gets clipped.
I tried solving it by specifying ItemTemplate:
<controls:Panorama.ItemTemplate>
<DataTemplate>
<ContentControl cal:View.Model="{Binding}"/>
</DataTemplate>
</controls:Panorama.ItemTemplate>
but that did not change a thing.
How would one solve this problem?
Well, the question is that apparently you can not. I tried overriding OnViewAttached
, finding the parent of my dynamically bound control (ContentControl
), but I was not able to retrieve its parent ( the PanoramaItem
I wanted to make wider).
So after much trial end error I settled on the following solution:
I define my panorama items explicitly in XAML:
<controls:PanoramaItem Header="item1">
<ContentControl x:Name="Control1"/>
</controls:PanoramaItem>
<controls:PanoramaItem Header="Wide Item" Width="700" Orientation="Horizontal">
<ContentControl x:Name="WideControl"/>
</controls:PanoramaItem>
They are also injected into the ViewModel and added to the collection of Items
, inherited from Caliburn's Cunductor
.
Then, I need to make sure that the ViewModel knows about the currently selected item, so the associated view can be activated by CaliburnMicro:
<controls:Panorama Name="MainPanorama"
cal:Message.Attach="[Event SelectionChanged] =
[Action MainPanorama_OnSelectionChanged($eventArgs)]"
SelectedIndex="{Binding ActivePage, Mode=TwoWay}">
I also make sure that the ViewModel receives the SelectionChanged
event, so it knows when to activate the currently visible item.
And finally the trick that makes it all work in ViewModel:
public void MainPanorama_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
ActivateItem(Items[ActivePage]);
}