Hi,
I am adding the TilePanes dynamically on the XamTileView. Is there a way to call other xaml pages as content in each of these tilePanes? If so, how?
Thanks,
Harish
Hello,
I got navigation sorted out. I am trying to load various xaml pages into each of the TilePane I create dynamically. However I am running to a couple of issues.
Here is the XAML template I have
<UserControl.Resources> <DataTemplate x:Key="UserTemplate"> <Image Stretch="Uniform" MaxWidth="100" HorizontalAlignment="Center" VerticalAlignment="Center"/> </DataTemplate> <DataTemplate x:Key="UserTemplateMaximized"> <StackPanel Loaded="StackMax_Loaded"> <navigation:Frame x:Name="navFrame" Margin="0"/> </StackPanel> </DataTemplate> <DataTemplate x:Key="UserTemplateMinimized"> <TextBlock x:Name="txtPane" FontSize="10" Loaded="stackMin_Loaded" /> </DataTemplate> </UserControl.Resources>
And here is my C# code behind
private void reportTileView_MaximizedStateChanged(object sender, Infragistics.Controls.Lists.TileStateChangedEventArgs e) { Infragistics.Controls.Lists.TilePane pane = e.Element as Infragistics.Controls.Lists.TilePane;
if (pane == null) return;
switch (e.NewState) { case Infragistics.Controls.Lists.TileState.Normal: pane.ContentTemplate = this.Resources["UserTemplate"] as DataTemplate; break; case Infragistics.Controls.Lists.TileState.Minimized: pane.ContentTemplate = this.Resources["UserTemplateMinimized"] as DataTemplate; if (oText != null) { ((TextBlock)this.oText).Text = "Some Description"; } break; case Infragistics.Controls.Lists.TileState.Maximized: pane.ContentTemplate = this.Resources["UserTemplateMaximized"] as DataTemplate; if (oFrame != null) { ((Frame)this.oFrame).Navigate(new Uri(((Reports)pane.Tag).URL, UriKind.Relative)); } break; default: break; } }
private void StackMax_Loaded(object sender, RoutedEventArgs e) { oFrame = (sender as FrameworkElement).FindName("navFrame"); }
private void stackMin_Loaded(object sender, RoutedEventArgs e) { oText = (sender as FrameworkElement).FindName("txtPane"); }
The issues I am facing is
1) For some reason, I never hit the states Normal and Minimized.
2) Since reportTileView_MaximizedStateChanged is hit before StackMax_Loaded, I never navigate to the desired page at the first time.
3) Subsequent attempts to maximize the panel forces me to navigate to the url. How can I avoid navigating to the url everytime I maximize a page once loaded?
Please help me resolve these. Thanks
Hi Harish, 1. Use the MinimizedStateChanging event; the MinimizedStateChanged event fires only for a tile that initiates maximizing or restoring the tile state2. It is hard to get an element from a DataTemplete. You have to use the VisualTreeHelper; it is better to use Binding - I am posting a sample code that will help you3. You cannot avoid navigating if you use data templates and different uri for each tileRegards,Marin
The sample code:<UserControl.Resources><DataTemplate x:Key="UserTemplate"> <TextBlock x:Name="txtPane" FontSize="10" Text="{Binding LongText}"/></DataTemplate><DataTemplate x:Key="UserTemplateMaximized"> <StackPanel> <sdk:Frame x:Name="navFrame" Margin="0" Source="{Binding URI}" /> </StackPanel></DataTemplate><DataTemplate x:Key="UserTemplateMinimized"> <TextBlock x:Name="txtPane" FontSize="10" Text="{Binding ShortText}"/></DataTemplate><DataTemplate x:Key="UserHeaderTemplate"> <TextBlock x:Name="txtPane" FontSize="10" Text="{Binding LongText}"/></DataTemplate></UserControl.Resources><Grid x:Name="LayoutRoot" Background="White"> <ig:XamTileView x:Name="reportTileView" ItemsSource="{Binding}" MaximizedStateChanging="reportTileView_MaximizedStateChanging" TilePaneContentTemplate="{StaticResource UserTemplate}" TilePaneHeaderTemplate="{StaticResource UserHeaderTemplate}"> </ig:XamTileView></Grid>
ObservableCollection<TileData> _data;public ObservableCollection<TileData> Data{ get { if (_data == null) { _data = new ObservableCollection<TileData>(); for (int i = 0; i < 9; i++) { _data.Add(new TileData { URI = new Uri("/Page.xaml", UriKind.RelativeOrAbsolute), LongText = "Normal " + i, ShortText = "Minimized " + i } ); } } return _data; }}private void reportTileView_MaximizedStateChanging(object sender, TileStateChangingEventArgs e) { TilePane pane = e.Element as TilePane; if (pane == null) return; switch(e.NewState) { case TileState.Normal: pane.ContentTemplate = this.Resources["UserTemplate"] as DataTemplate; break; case TileState.Maximized: pane.ContentTemplate = this.Resources["UserTemplateMaximized"] as DataTemplate; break; case TileState.Minimized: pane.ContentTemplate = this.Resources["UserTemplateMinimized"] as DataTemplate; break; }}public class TileData : INotifyPropertyChanged{ private Uri _URI; public Uri URI { get { return this._URI; } set { if (this._URI != value) { this._URI = value; this.OnPropertyChanged("URI"); } } } private string _shortText; public string ShortText { get { return this._shortText; } set { if (this._shortText != value) { this._shortText = value; this.OnPropertyChanged("ShortText"); } } } private string _longText; public string LongText { get { return this._longText; } set { if (this._longText != value) { this._longText = value; this.OnPropertyChanged("LongText"); } } } public event PropertyChangedEventHandler PropertyChanged; virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }}}public SLUserControl(){ InitializeComponent(); this.DataContext = this.Data;}
Harish,
You can dynamically add TilePanes to the XamTileView by adding items to the collection which is set as the DataContext. The attached sample demonstrates this concept.
The state of the content of the TilePanes can be maintained again by maintaining the view-related information in your ViewModel. Instead of loading separate DataTemplates depending on the state of the TilePane, you can bind the Visibility of the different elements of your UI to the DataContext of the Pane OR you can set a DataContext to the Silverlight Page to which you are navigating.
If there are any further details you are unsure of please let me know.