Using a progress indicator that gets hidden within a Panorama control is causing the panorama item to just to 1st one - windows-phone-8

I have a really strange and annoying issue on my WP8 app.
It's using a Panorama control to view items that it downloads from the Net. It has a view that is displayed whilst it's downloading content but then gets collapsed after the content has completed loading.
When the "loading" view is collapsed I'm finding that the Panorama control jumps back to the first item in the control regardless of what item you have selected.
I have the following very basic test code that demonstrates the issue.
XAML:
<phone:PhoneApplicationPage
x:Class="Wp8.GUI.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:converters="clr-namespace:Wp8.Gui.Converters"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.Resources>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Grid.Resources>
<phone:Panorama ItemsSource="{Binding PanoramaItems}">
<phone:Panorama.HeaderTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<TextBlock Text="{Binding Title}" />
</Grid>
</DataTemplate>
</phone:Panorama.HeaderTemplate>
<phone:Panorama.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel x:Name="Visible1" Visibility="{Binding ShowFirst, Converter={StaticResource BooleanToVisibilityConverter},ConverterParameter=True}" >
<ProgressBar IsIndeterminate="True" />
<TextBlock Text="ShowFirst" />
</StackPanel>
<StackPanel x:Name="Visible2" Visibility="{Binding ShowFirst, Converter={StaticResource BooleanToVisibilityConverter},ConverterParameter=False}" >
<TextBlock Text="Show Second" />
</StackPanel>
</Grid>
</DataTemplate>
</phone:Panorama.ItemTemplate>
</phone:Panorama>
</Grid>
</phone:PhoneApplicationPage>
The VM and Code Behind is as follows:
namespace Wp8.GUI
{
public class PanItemVm : INotifyPropertyChanged
{
private readonly string _title;
private bool _showFirst = true;
public PanItemVm()
{
_title = "Control";
}
public PanItemVm(string title)
{
_title = title;
}
public string Title { get { return _title; } }
public bool ShowFirst
{
get { return _showFirst; }
set
{
_showFirst = value;
RaisePropertyChanged("ShowFirst");
}
}
private void RaisePropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class PanItemVm2 : PanItemVm
{
public PanItemVm2() : base ("Items")
{
Task.Run(() => Task.Delay(TimeSpan.FromSeconds(5)))
.ContinueWith(t => ShowFirst = false,
TaskScheduler.FromCurrentSynchronizationContext());
}
}
public class TestVm : INotifyPropertyChanged
{
public IEnumerable<PanItemVm> PanoramaItems
{
get {
return Enumerable.Range(0, 2)
.Select(i => i == 0 ?
new PanItemVm() : new PanItemVm2()); }
}
public event PropertyChangedEventHandler PropertyChanged;
}
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
DataContext = new TestVm();
}
}
}
If you run up the code in an emulator and then flick to Item2 in the Panorama. After 5 seconds it'll flick back to the page marked "Control".
In this test code I can get around the problem by either
a) Changing the StackPanel that the ProgressIndicator is contained in to a Grid
b) Removing the ProgressIndicator
Neither of these solutions work for my proper project however but if I remove Visibility code that uses the BooleanToVisibilityConverter then it doesn't flick back.
Does anybody have any ideas what might be causing this?
I can post the entire sample code if that's useful.
Thanks
--- EDIT ---
Here is the code for the BooleanToVisibilityConverter
using System.Windows;
using System.Windows.Data;
namespace Wp8.Gui.Converters
{
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && value is bool)
{
bool visibilityValue = true;
if(parameter != null)
{
if(parameter is string)
{
bool.TryParse((string)parameter, out visibilityValue);
}
}
return (bool)value == visibilityValue ? Visibility.Visible : Visibility.Collapsed;
}
return Visibility.Visible;
}
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
}

I've been having the same problem. I have a Panorama (modified to fill the full screen) that I'm using to display pictures in a carousel. I have to turn the pictures on/off based on Panorama position to keep the memory low. However, whenever a picture loads, the panorama returns to the default item... the first item.
So I took a hint from another question and went to look at the source code for Panorama. While you can't see the current code, you can see what Panorama was when it was part of the WP Toolkit. It seems that anytime there is a change in size of the panorama, the internal scrollviewer is reset.
void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
// clip to control layout
LayoutRoot.SetValue(Panel.ClipProperty, new RectangleGeometry() { Rect = new Rect(0, 0, this.Width, this.Height) });
// reset scroll viewer
Dispatcher.BeginInvoke(() =>
{
ScrollView.Invalidate(false);
});
}
OK. That was a clue. So I played around with my itemtemplate (my header is non-existent) trying to see what was changing size. SOMETHING was changing size... not sure what. So I wrapped everything in a Grid and hardcoded the Width/Height/MaxWidth/MaxHeight to be equal to the Screen Height/Width. They are bound to calculated values in my viewmodel that change according to device orientation.
<controls:PanoramaFullScreen.ItemTemplate>
<DataTemplate>
<Grid Width="{Binding LayoutWidth}"
MaxWidth="{Binding LayoutWidth}"
Height="{Binding LayoutHeight}"
MaxHeight="{Binding LayoutHeight}">
{rest of stuff}
</Grid>
</DataTemplate>
It works! No more switching back to item one!
So I suspect your code is changing the overall height/width of a PanoramaItem, which is in turn changing the Panorama size and resetting the internal scrollviewer.

Related

MVVMcross Command Binding fire Exception

I experience an issue when i try to use a command to open a Second View Model V4.0.Beta5.
I followed the Exemple described in N+1 Video series https://www.youtube.com/playlist?list=PLR6WI6W1JdeYSXLbm58jwAKYT7RQR31-W
First ViewModel
public class FirstViewModel
: MvxViewModel
{
private string _hello = "Hello MvvmCross";
public string Hello
{
get { return _hello; }
set
{
_hello = value;
RaisePropertyChanged(() => Hello);
}
}
private Cirrious.MvvmCross.ViewModels.MvxCommand _goSecondViewCommand;
public System.Windows.Input.ICommand GoSecondViewCommand
{
get
{
_goSecondViewCommand = _goSecondViewCommand ??
new Cirrious.MvvmCross.ViewModels.MvxCommand(DoGoSecondView);
return _goSecondViewCommand;
}
}
private void DoGoSecondView()
{
base.ShowViewModel<SecondViewModel>();
}
}
Second View model
public class SecondViewModel :MvxViewModel
{
private string _hello2 = "Hello2 MvvmCross";
public string Hello2
{
get { return _hello2; }
set
{
_hello2 = value;
RaisePropertyChanged(() => Hello2);
}
}
}
First View
<views:MvxWindowsPage
x:Class="TestCommand.UWP.Views.FirstView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestCommand.UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="using:Cirrious.MvvmCross.WindowsUWP.Views"
mc:Ignorable="d">
<Grid>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Margin="70,92,0,0" TextWrapping="Wrap" Text="FirstView" VerticalAlignment="Top" Width="223"/>
<Button x:Name="button" Command="{Binding GoSecondViewCommand}" Content="Button" HorizontalAlignment="Left" Height="108" Margin="70,346,0,0" VerticalAlignment="Top" Width="223"/>
</Grid>
Second view
<views:MvxWindowsPage
x:Class="TestCommand.UWP.Views.SecondView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestCommand.UWP.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="using:Cirrious.MvvmCross.WindowsUWP.Views"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid />
Setup Class:
public class Setup : MvxWindowsSetup
{
public Setup(Frame rootFrame) : base(rootFrame)
{
}
protected override IMvxApplication CreateApp()
{
return new TestCommand.Core.App();
}
}
If you want you can download the solution Here:
https://onedrive.live.com/redir?resid=A5D9789788DE33CB!36079&authkey=!AKs9nsG28iI6nQQ&ithint=file%2czip.
The possible reason is you don't use Setup correctly in your UWP app, here is what I do to make this work:
1) Create two ViewModels in the UWP app: FirstViewModel and SecondViewModel
2) Create a Setup class in Setup.cs file:
public class Setup : MvxWindowsSetup
{
public Setup(Frame rootFrame) : base(rootFrame)
{
}
protected override IMvxApplication CreateApp()
{
return new AppSetup();
}
}
public class AppSetup : MvxApplication
{
public override void Initialize()
{
RegisterAppStart<FirstViewModel>();
}
}
3) FirstView.xaml:
<StackPanel>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Margin="70,92,0,0" TextWrapping="Wrap" Text="FirstView" VerticalAlignment="Top" Width="223"/>
<TextBlock Height="50" Text="{Binding Hello}" />
<Button x:Name="button" Command="{Binding GoSecondViewCommand}" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="223" Height="50" />
</StackPanel>
4) SecondView.xaml:
<StackPanel>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Margin="70,92,0,0" TextWrapping="Wrap" Text="SecondView" VerticalAlignment="Top" Width="223"/>
<TextBlock Height="50" Text="{Binding Hello2}" />
</StackPanel>
5) In App.xaml.cs file, make the following changes in OnLaunched method:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
......
if (rootFrame.Content == null)
{
var setup = new Setup(rootFrame);
setup.Initialize();
var start = Mvx.Resolve<IMvxAppStart>();
start.Start();
}
// Ensure the current window is active
Window.Current.Activate();
}
By the way, the MvvmCross version is 3.5.1
Check the Completed sample on Github
Update for exception in OnNavigationFailed method:
Please comment this line in FirstView and SecondView's code behind:
ViewModel = new FirstViewModel();
ViewModel = new SecondViewModel();
The MvvmCross has set the ViewModel automatically.

Convertion of long in Windows store application

I am writing a windows 8 store application and have the following problem:
I have a textblock binded to a long property of an object.
The long value is 123456789, however, on the screen i only see the char 1.
How can i solve this, and why the convertion to string doesn't work like it should?
Try this and let me if it works for you or not.
XAML
<Page.DataContext>
<local:myVm />
</Page.DataContext>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<GridView ItemsSource="{Binding col}">
<GridView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Margin="20" FontSize="20" />
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid MaximumRowsOrColumns="3" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
</Grid>
myVm.cs
public class myVm : INotifyPropertyChanged
{
public myVm()
{
col.Add(long.MaxValue);
col.Add(long.MaxValue);
col.Add(long.MaxValue);
col.Add(long.MaxValue);
col.Add(long.MaxValue);
col.Add(long.MaxValue);
}
private ObservableCollection<long> _col = new ObservableCollection<long>();
public ObservableCollection<long> col
{
get { return _col; }
set
{
_col = value;
NotifyPropertyChanged("col");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
}

using Gridview control inside a usercontrol

I am trying create UserControl with below requirements.
Usercontrol contains a gridview and in side gridview, I need to add a button element. So, the idea is :- if usercontrol is used in any other page by providing a collection to ItemSource then list of buttons should be generated and Button content value should be one of the property value of type present in Itemsource collection.
I am pretty newbie to windows store app programming. I am trying to expose the gridview ItemSources property by creating dependency property so that ObservableCollection of any type can be mapped and trying expose a dependency property to bind to button content property. but not able to achieve the same. I would really appreciate if you could point to a sample application doing the same.
Thanks a lot in advance.
here is a small sample (i hope that's what you wanna do)...
EDIT: I finally edited my answer to provide the property which takes the property path. IF ANYONE HAS ANOTHER SOLUTION FOR THIS QUESTION, PLEASE LET ME KNOW!
Add a dependency property for the binding path:
First we create a dummy model which provides the title for our buttons:
public class SampleModel
{
public string Title { get; set; }
}
Then, the usercontrol. The important thing here is the ItemsSource-Binding (ElementName = UserControl). Otherwise you'll bind to the UserControlItemsSource in the Parent-DataContext.
EDIT: The button has changed since my last answer!
<UserControl
x:Class="StackOverflow.ListUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:StackOverflow"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
x:Name="SampleUserControl">
<Grid>
<ListView ItemsSource="{Binding UserControlItemsSource, ElementName=SampleUserControl}" Background="DeepSkyBlue" SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<Button Loaded="FrameworkElement_OnLoaded"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</UserControl>
... and the usercontrol's code-behind including the UsercontrolItemsSource:
EDIT: i added the dependency property BindingPropertyPath and the FrameworkElement_OnLoaded method since my last answer.
public sealed partial class ListUserControl : UserControl
{
public ObservableCollection<SampleModel> UserControlItemsSource
{
get { return (ObservableCollection<SampleModel>)GetValue(UserControlItemsSourceProperty); }
set { SetValue(UserControlItemsSourceProperty, value); }
}
// Using a DependencyProperty as the backing store for UserControlItemsSource. This enables animation, styling, binding, etc...
public static readonly DependencyProperty UserControlItemsSourceProperty =
DependencyProperty.Register("UserControlItemsSource", typeof(ObservableCollection<SampleModel>), typeof(ListUserControl), new PropertyMetadata(null));
public string BindingPropertyPath
{
get { return (string)GetValue(BindingPropertyPathProperty); }
set { SetValue(BindingPropertyPathProperty, value); }
}
// Using a DependencyProperty as the backing store for BindingPropertyPath. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BindingPropertyPathProperty =
DependencyProperty.Register("BindingPropertyPath", typeof(string), typeof(ListUserControl), new PropertyMetadata(string.Empty));
public ListUserControl()
{
this.InitializeComponent();
}
private void FrameworkElement_OnLoaded(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
Binding contentBinding = new Binding();
contentBinding.Path = new PropertyPath(this.BindingPropertyPath);
button.SetBinding(Button.ContentProperty, contentBinding);
}
}
Now we add the usercontrol to our main page (ListPageHost):
EDIT: Set the new dependency property BindingPropertyPath to the name of the property of the ItemsSource that you wanna use for the button.
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="Add Item to ItemsSource" Click="ButtonBase_OnClick"></Button>
<local:ListUserControl Grid.Row="1" UserControlItemsSource="{Binding SampleCollection}" BindingPropertyPath="Title"/>
</Grid>
In the mainpage's code-behind, we declare our mainpage-viewmodel (ListPageHostViewModel):
public class ListPageHostViewModel
{
private readonly ObservableCollection<SampleModel> _sampleCollection = new ObservableCollection<SampleModel>();
public ObservableCollection<SampleModel> SampleCollection
{
get { return _sampleCollection; }
}
}
... and the MainPage's (ListPageHost) code behind:
public sealed partial class ListPageHost : Page
{
public ListPageHost()
{
this.InitializeComponent();
this.DataContext = new ListPageHostViewModel();
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
var vm = this.DataContext as ListPageHostViewModel;
if (vm != null)
{
vm.SampleCollection.Add(new SampleModel() { Title = string.Format("new item {0}", DateTime.Now.Ticks)});
}
}
}
Hope that's what you're looking for. If you have any questions - let me know.
Regards, Alex

Virtualize the loading of Windows 8 XAML controls within a grid

I have a Window 8 RT store application (XAML/C#).
I have a form with a grid as the main component. That grid has 50 rows and each row has a TextBox. The grid is wrapped in a scrollviewer:
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
...50 rows
</Grid.RowDefinitions>
<TextBox Grid.Row="0" />
<TextBox Grid.Row="1" />
<TextBox Grid.Row="2" />
...
<TextBox Grid.Row="50" />
</Grid>
</ScrollViewer>
When this form is loaded there is a notable pause while the page is loaded, I guessing this is because the page is being drawn.
What is the best way to speed this load process up? Can I virtualize the loading of the grid/Textboxes?
The slowness is notable once the application is running on a Windows Surface tablet, it's not bad on my design PC but that is obviously much more powerful.
Thanks in advance.
You can use a ListView instead of the Grid in a ScrollViewer since that supports virtualization by default. Other than that - it might be nice to have some nicer user experience than a scary long list of TextBoxes to fill - maybe break up your form in multiple pages or use a FlipView to flip between groups of fields.
*EDIT - example
XAML
<Page
x:Class="App10.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App10"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<DataTemplate
x:Key="TextFieldTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition
Height="Auto" />
<RowDefinition
Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
Text="{Binding Label}" />
<TextBox
Text="{Binding Value, Mode=TwoWay}"
Grid.Row="1" />
</Grid>
</DataTemplate>
<DataTemplate
x:Key="BoolFieldTemplate">
<CheckBox
Content="{Binding Label}"
IsChecked="{Binding Value, Mode=TwoWay}" />
</DataTemplate>
<local:FieldTemplateSelector
x:Key="FieldTemplateSelector"
TextTemplate="{StaticResource TextFieldTemplate}"
BoolTemplate="{StaticResource BoolFieldTemplate}" />
</Page.Resources>
<Grid
Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<ListView
x:Name="lv"
ItemTemplateSelector="{StaticResource FieldTemplateSelector}" />
</Grid>
</Page>
C#
using System.Collections.Generic;
using App10.Common;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace App10
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.lv.ItemsSource =
new List<object>(
new object[]
{
new BoolFieldViewModel { Label = "Some bool field" },
new TextFieldViewModel { Label = "Some text field" },
new TextFieldViewModel { Label = "Some text field" },
new BoolFieldViewModel { Label = "Some bool field" },
new BoolFieldViewModel { Label = "Some bool field" },
new TextFieldViewModel { Label = "Some text field" },
});
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
}
public abstract class FieldViewModel<T> : BindableBase
{
public string Label { get; set; }
#region Value
private T _value;
public T Value
{
get { return _value; }
set { this.SetProperty(ref _value, value); }
}
#endregion
}
public class BoolFieldViewModel : FieldViewModel<bool> { }
public class TextFieldViewModel : FieldViewModel<string> { }
public class FieldTemplateSelector : DataTemplateSelector
{
public DataTemplate BoolTemplate { get; set; }
public DataTemplate TextTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
if (item is BoolFieldViewModel) return BoolTemplate;
if (item is TextFieldViewModel) return TextTemplate;
return base.SelectTemplateCore(item, container);
}
}
}

ICommand will not trigger

My ICommand will not trigger unless I move the DataContext field into the the DataTemplate (contlisttemplate) for the Button. I have images set in a style resource, those disappear as soon as I move the DataContext field into the DataTemplate. Both images and ICommand should be using the same DataContext so I am unsure of why it will not work.
Here is a snippet of my code below.
DataContext="{Binding LongListViewModel, Source={StaticResource viewModelLocator}}"
<i:Interaction.Behaviors>
<GamePad:XboxBehavior StartFocusControlName="continuousList1" IsTopLevelViewForFocus="True"/>
</i:Interaction.Behaviors>
<UserControl.Resources>
<DataTemplate x:Key="contlisttemplate" >
<Button
Command="{Binding Gotodetailpage}"
Style="{StaticResource custherotile}">
</Button>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<xbox:ContinuousList
HorizontalAlignment="Left"
Name="continuousList1"
VerticalAlignment="Top"
ItemTemplate="{StaticResource contlisttemplate}"
ItemsSource="{Binding LongListItems}" Height="316" Width="1280"
Grid.Row="1"
>
<i:Interaction.Behaviors>
<GamePad:XboxBehavior IsContinuousListVuiEnabled="True" HasFocusRetention="True"/>
</i:Interaction.Behaviors>
</xbox:ContinuousList>
public class LongListViewModel : ViewModelBase<LongListViewModel>
{
private readonly IDialogService dialogService;
public Navigateto compass = new Navigateto();
public LongListViewModel()
{
LongListItems = new ObservableCollection<object>();
dictionaryListwithkey = new Dictionary<string, object>();
Gotodetailpage = new RelayCommand(PerformGotoDetailPage);
}
public LongListViewModel(IDialogService dialogService)
: this()
{
this.dialogService = dialogService;
}
public Program getherovideo
{
get { return (Program)LongListItems[0]; }
set
{
//SetProperty(ref currentVideo, value,x => x.CurrentVideo);
}
}
public ObservableCollection<object> LongListItems
{
get;
set;
}
public Dictionary<string, object> dictionaryListwithkey
{
get;
set;
}
public ICommand Gotodetailpage { get; private set; }
private void PerformGotoDetailPage()
{
// Console.WriteLine("List item clicked");
compass.goToDetailsPageWithPath("89");
}
}
In case anyone was wondering what the answer was . As per Aaron Hill ATG :
This looks like an issue of scope. The outer DataContext is your LongListViewModel class, which contains the desired ICommand, but the ItemsSource for the container is set to the LongListItems collection exposed by the view-model. This means the effective DataContext for the DataTemplate is an individual member of the collection, not the overall view-model.
Overriding the DataContext of the DataTemplate would let you point back to the view-model and access the ICommand, however it also means you lose any data present within the individual elements of the LongListItems collection. That is probably why the images no longer work in this case.
Since each item in the collection has its own button, it probably makes sense for the ICommand property to be exposed on the individual item rather than the view-model.