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();
}
}
}
BooleanToVisibilityConverter
. I removed the references to this and ran the code but it doesn't reproduce the issue you're experiencing – Matt Lacey