how to get the checkbox value from the LongListSelector in wp8 - windows-phone-8

My Longlistselector DataTemplate
<DataTemplate x:Key="NotesListBoxItemTemplate">
<Grid HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<CheckBox
Grid.Column="0" Grid.Row="0" Grid.RowSpan="2"
x:Name="chkDelete"
Visibility="Visible" Tap="chkDelete_Tap" Margin="0,36,0,0" />
<TextBlock
Text="{Binding NoteName}"
FontSize="{StaticResource PhoneFontSizeLarge}"
FontFamily="Segoe WP"
Grid.Row="0" Grid.Column="1" Margin="12,24,0,0" />
</Grid>
</DataTemplate>
and my Longlist selector is
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ScrollViewer>
<phone:LongListSelector
x:Name="MainListBox"
ItemsSource="{Binding AllData}"
Margin="12, 0, 12, 0"
ItemTemplate="{StaticResource ListBoxItemTemplate}" />
</ScrollViewer>
</Grid>
How do I loop through the items and get the Checkbox checked state in each item? Previously I used ListBox and its worked correctly. And I am able to find out the checkbox value of the each item using below code
private T FindFirstElementInVisaulTree<T>(DependencyObject parentElement) where T:DependencyObject
ListBoxItem passed as a DependencyObject. The only problem with ListBox is scrolling. So trying for LongListSelector.
Please how do i loop through the items in LongListSelector.
Thank you

You can also Data Bind the state of the checkbox to your Model. Then you can just loop through the MainListBox.ItemsSource. If you do it this way you need to set the Binding Mode=Two Way or the collection will not change once someone taps the Checkbox. I would also recommend you use a Command to handle the Tap event on the Checkbox so you can handle in your ViewModel rather then Code behind. Here's my quick example modified from previous solutions I have posted:
// Namespaces used
using System.Collections.ObjectModel; // ObservableCollection<T>
using System.ComponentModel; // INotifyPropertyChanged
// sample_data class
public class sample_data : INotifyPropertyChanged
{
// simple constructor
public sample_data(string noteName, Boolean checkboxState)
{
this.NoteName = noteName;
this.CheckboxState = checkboxState;
}
// implement the INotify
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
// {Binding Properties}
Boolean checkbox_state;
public Boolean CheckboxState
{
get { return checkbox_state; }
set { checkbox_state = value; NotifyPropertyChanged("CheckboxState"); }
}
string note_name;
public string NoteName
{
get { return note_name; }
set { note_name = value; NotifyPropertyChanged("NoteName"); }
}
}
// create a sample set of data to show
private ObservableCollection<sample_data> CreateData()
{
ObservableCollection<sample_data> my_list = new ObservableCollection<sample_data>();
my_list.Add(new sample_data("one", false));
my_list.Add(new sample_data("two", true));
my_list.Add(new sample_data("three", false));
my_list.Add(new sample_data("four", true));
my_list.Add(new sample_data("five", false));
my_list.Add(new sample_data("six", true));
my_list.Add(new sample_data("seven", false));
my_list.Add(new sample_data("eight", true));
return my_list;
}
public MainPage()
{
InitializeComponent();
MainListBox.ItemsSource = CreateData(); // set the data bind
}
/// You can loop through the items like this, use any convention you want.
private void LoopThroughItems()
{
foreach (sample_data sd in MainListBox.ItemsSource)
{
Boolean is_check = sd.CheckboxState;
}
}
Your DataTemplate needs to change so it Databinds the checkbox with two-way binding.
<DataTemplate x:Key="NotesListBoxItemTemplate">
<Grid HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0" IsChecked="{Binding CheckboxState, Mode=TwoWay}" Grid.Row="0" Grid.RowSpan="2" x:Name="chkDelete" Visibility="Visible" Margin="0,36,0,0" />
<TextBlock Text="{Binding NoteName}" FontSize="{StaticResource PhoneFontSizeLarge}" FontFamily="Segoe WP" Grid.Row="0" Grid.Column="1" Margin="12,24,0,0" />
</Grid>
</DataTemplate>

Related

Bindings not set for items not visible

Sorry if this is a dumb question. I am maintaining this crazy Windows Phone 8.1 RT dynamic app that I didn't write. It loads up a whole bunch of stuff to the DataContext. Things that aren't visible on the screen don't seem to get their DataContext. When I navigate away from the form the event fires. What do I need to do to fix that? Even when it scrolls into view it doesn't load. If I scoll up and click the back button I see the field populate before it goes to the previous page.
Edit - Here is some code:
<DataTemplate x:Key="com.somecompany.BarcodeboxRenderer">
<Grid HorizontalAlignment="Stretch" DataContext="{Binding Item1}">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Label}" HorizontalAlignment="Stretch" Style="{StaticResource labelstyle}" Grid.Row="0" />
<somecompany:BarcodeBox IsReadOnly="{Binding DisplayOnly}" somecompany:DynamicDataBindingPath.BindingPath="{Binding FieldId}" Grid.Row="1" />
</Grid>
</DataTemplate>
That calls this but only if it's visible:
public sealed class DynamicDataBindingPath:FrameworkElement
{
public static readonly DependencyProperty BindingPathProperty = DependencyProperty.RegisterAttached("BindingPath", typeof(string), typeof(DynamicDataBindingPath), new PropertyMetadata("", OnBindingPathPropertyChanged));
public static string GetBindingPath(FrameworkElement target)
{
try
{
return (string)target.GetValue(BindingPathProperty);
}
catch (Exception)
{
return string.Empty;
}
}
public static void SetBindingPath(FrameworkElement target, string value)
{
target.SetValue(BindingPathProperty, value);
target.Loaded += Target_Loaded;
}
private static void Target_Loaded(object sender, RoutedEventArgs e) {
var target = (FrameworkElement)sender;
if (target is ...) { ... }
else if (target is DatePicker)
{
int startingletterindex = value.IndexOf('.') + 1;
string pathtobindto = "obj." + Char.ToUpper(value[startingletterindex]) + value.Substring((startingletterindex + 1));
Binding newbind = new Binding();
newbind.Path = new PropertyPath(pathtobindto);
var contextsrc = findRealDataContext(target);
newbind.Source = contextsrc.DataContext;
newbind.Mode = BindingMode.TwoWay;
(target as DatePicker).SetBinding(DatePicker.DateProperty, newbind);
}
else if (...)
}
I turned of ListView Virtualization and it works now. I don't need it because there will never be more than a handful of rows.

Playing videos from RSS feed in windows phone

I have parsed the RSS feed http://www.teluguone.com/videosongs/videoSongsXml.php?cat_id=6 and displayed in listbox.When i click on a particular song automatically it should be navigated and start playing.But when i click on a song it is navigating to other page but not playing.It was displaying "An error occured please try again".I am not understanding where the problem is.I have written the following code.No errors and warnings are rising.
please help me.i was trying on this from many days.
Maipage.Xaml:
<phone:PhoneApplicationPage
x:Class="videosongs.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:delay="clr-namespace:Delay;assembly=PhonePerformance"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True" Loaded="PhoneApplicationPage_Loaded">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="Teluguone" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="Videosongs" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="songsList"
SelectionChanged="songsList_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="130">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image delay:LowProfileImageLoader.UriSource="{Binding songpic}"
Grid.Column="0"
Width="97"
Height="125"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="6"/>
<StackPanel Margin="10,15,0,0"
Grid.Column="1"
Height="60"
Orientation="Horizontal"
VerticalAlignment="Top">
<TextBlock Text="{Binding songname}"
FontSize="30" />
</StackPanel>
<StackPanel Margin="0,50,0,0"
Grid.Column="1"
VerticalAlignment="Center">
<TextBlock Grid.Column="1"
Text="{Binding songdescr}"
Style='{StaticResource PhoneTextSubtleStyle}'
/>
<TextBlock Grid.Column="1"
Text="{Binding songdate}"
Style='{StaticResource PhoneTextSubtleStyle}'
/>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ProgressBar x:Name="progress" Foreground="White" />
</Grid>
</Grid>
Mainpage.xaml.cs:
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
// is there network connection available
if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
MessageBox.Show("No network connection available!");
return;
}
// start loading XML-data
WebClient downloader = new WebClient();
Uri uri = new Uri("http://www.teluguone.com/videosongs/videoSongsXml.php?cat_id=6", UriKind.Absolute);
downloader.DownloadStringCompleted += new DownloadStringCompletedEventHandler(VideosongsDownloaded);
downloader.DownloadStringAsync(uri);
}
void VideosongsDownloaded(object sender, DownloadStringCompletedEventArgs e)
{
try
{
if (e.Result == null || e.Error != null)
{
MessageBox.Show("There was an error downloading the XML-file!");
}
else
{
// Deserialize if download succeeds
XDocument document = XDocument.Parse(e.Result);
XmlSerializer serializer = new XmlSerializer(typeof(Videosongs));
Videosongs videosongs = (Videosongs)serializer.Deserialize(document.CreateReader());
songsList.ItemsSource = videosongs.Collection;
}
}
catch (Exception ex)
{
//MessageBox.Show(ex.InnerException.Message);
MessageBox.Show(ex.ToString());
}
}
// selection in SongsdetailsList is changed
private void songsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox listBox = sender as ListBox;
if (listBox != null && listBox.SelectedItem != null)
{
Songsdetails song = (Songsdetails)listBox.SelectedItem;
System.Diagnostics.Debug.WriteLine(song);
NavigationService.Navigate(new Uri("/Videopage.xaml?songsongcode=" + song.songcode , UriKind.Relative));
}
}
}
}
Songsdetails.cs:
public class Songsdetails
{
[XmlElement("songname")]
public string songname { get; set; }
[XmlElement("songpic")]
public string songpic { get; set; }
[XmlElement("songcode")]
public string songcode { get; set; }
[XmlElement("songdescr")]
public string songdescr { get; set; }
[XmlElement("songtitletags")]
public string songtitletags { get; set; }
[XmlElement("songmetatags")]
public string songmetatags { get; set; }
[XmlElement("songmetadesc")]
public string songmetadesc { get; set; }
[XmlElement("songdate")]
public string songdate { get; set; }
[XmlElement("songurl")]
public string songurl { get; set; }
Videosongs.cs:
[XmlRoot("videosongs")]
public class Videosongs
{
//[XmlElement("publisher")]
//public string publisher { get; set; }
//[XmlElement("publisherurl")]
//public string publisherUrl { get; set; }
[XmlElement("songsdetails")]
public ObservableCollection<Songsdetails> Collection { get; set; }
Videopage.Xaml:
<phone:PhoneApplicationPage
x:Class="videosongs.Videopage"
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:extended="clr-namespace:MyToolkit.Controls;assembly=MyToolkit.Extended"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Landscape"
shell:SystemTray.IsVisible="False">
<StackPanel VerticalAlignment="Top" Height="600" Margin="0,0,0,0">
<TextBlock x:Name="title" TextWrapping="Wrap" VerticalAlignment="Top" Height="40"></TextBlock>
<phone:WebBrowser x:Name="webBrowser" Height="411" IsScriptEnabled="True" Margin="10,0,78,0" />
</StackPanel>
Videopage.Xaml.cs:
namespace videosongs
{
public partial class Videopage : PhoneApplicationPage
{
// Constructor
public Videopage()
{
InitializeComponent();
}
// When page is navigated to set data context to selected item in list
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
if (!NetworkInterface.GetIsNetworkAvailable())
{
MessageBox.Show("An error has occurred! Please verify your internet connection.");
NavigationService.GoBack();
}
else
{
string video = "http://www.youtube.com/embed/+getsongcode()";
System.Diagnostics.Debug.WriteLine(video);
this.webBrowser.Navigate(new Uri(video));
}
}
}
Anybody please help.Any help would be appreciated.
Many Thanks in advance.

Error when trying to tap on LongListSelector

I've made a JumpList (by following this tutorial) linked with a LongListSelector, but I can't redirect the user when he taps on an item of the list. I used to do it well with a simple LongListSelector as this one :
<phone:LongListSelector x:Name="lls_Songs" SelectionChanged=lls_Songs_SelectionChanged>
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Margin="5,5,5,5">
<TextBlock Text="{Binding Name}" FontSize="30"/>
<TextBlock Text="{Binding Duration}" FontSize="20" Opacity="0.75"/>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
But now I use this code...
<phone:LongListSelector
x:Name="lls_songs"
Margin="12,35,12,0"
Visibility="Visible"
JumpListStyle="{StaticResource JumpListStyle}"
Background="Transparent"
GroupHeaderTemplate="{StaticResource lls_SongsHeaderTemplate}"
ItemTemplate="{StaticResource lls_SongsTemplate}"
LayoutMode="List"
IsGroupingEnabled="true"
SelectionChanged="lls_songs_SelectionChanged"
HideEmptyGroups ="true"/>
...linked with this code :
<DataTemplate x:Key="lls_SongsTemplate">
<StackPanel VerticalAlignment="Top" Orientation="Horizontal" Margin="5,5,5,5">
<StackPanel Orientation="Vertical">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="détails"/>
<toolkit:MenuItem Header="ajouter à la lecture"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<TextBlock Text="{Binding songName}" FontSize="30" />
<TextBlock Text="{Binding songArtist}" FontSize="20" Opacity="0.75"/>
</StackPanel>
</StackPanel>
</DataTemplate>
here is the lls_Songs_SelectionChanged method :
private void lls_songs_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Song _selectedSong = lls_songs.SelectedItem as Song;
MediaPlayer.Play(_selectedSong);
}
and finaly how I create my songs list :
MediaLibrary _library = new MediaLibrary();
List<MusicInfo> MusicInfoList = new List<MusicInfo>();
int so = _library.Songs.Count;
int _so = 0;
while(_so < so)
{
Song _song = null;
_song = _library.Songs[_so];
MusicInfoList.Add(new MusicInfo(_song.Name, _song.Artist.ToString()));
_so = _so + 1;
}
linked with this class:
public string songName { get; set; }
public string songArtist { get; set; }
public MusicInfo(string _songName, string _songArtist)
{
this.songName = _songName;
this.songArtist = _songArtist;
}
and the jumplist :
private void SortingSongsListsAZ()
{
List<AlphaKeyGroup<MusicInfo>> DataSource = AlphaKeyGroup<MusicInfo>.CreateGroups(MusicInfoList,
System.Threading.Thread.CurrentThread.CurrentUICulture,
(MusicInfo s) => { return s.songName; }, true);
lls_songs.ItemsSource = DataSource;
}
And when I tap on an item of the list, I get this error : "This method does not accept null for this parameter". I don't understand why, anyone would help me ?
Share or check your lls_songs items source binding and code. from your code it appears that
Song _selectedSong = lls_songs.SelectedItem as Song;
_selectedSong is null.
in debug mode see what is the value of SelectedItem. is it Song type or something else?
According to your update, it seems that lls_songs.SelectedItem is of type MusicInfo instead of Song. Fixing your type-casting should remove the error I believe :
MusicInfo _selectedSong = lls_songs.SelectedItem as MusicInfo;
Or better yet this way :
MusicInfo _selectedSong = (MusicInfo)lls_songs.SelectedItem;

Viewing the top items in a LongListSelector on WP8 when SIP is open

I have an app that uses a LongListSelector to display a list of items, at the bottom of the page I have a TextBox. When the TextBox is tapped, the SIP displays itself. At this point, I'm unable to then scroll to the top of the LLS.
Sample code:
XAML:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<phone:LongListSelector x:Name="TheList">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"
Style="{StaticResource PhoneTextLargeStyle}"/>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
<Grid Grid.Row="1">
<TextBox />
</Grid>
</Grid>
C#:
public MainPage()
{
InitializeComponent();
Loaded += (sender, args) =>
{
var list = new List<string>();
for (var i = 0; i < 30; i++)
{
list.Add("This is string number " + i);
}
TheList.ItemsSource = list;
};
}
This is as much as I can see, I can pull down to string number 5, but can't see any higher:
Anyone got any ideas?
The ScrollViewer doesn't take into account the SIP so its scrolling experience is the same as when the SIP is not visible (which is why the top can't be reached). One workaround would be to add a margin to the top of the LongListSelector, (or the bottom if your textbox is at the top), when the SIP is displayed.
As there's no event for the SIP, you can handle the GotFocus and LostFocus events of the TextBox. (The 180 value was obtained via trial and error)
private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
TheList.Margin = new Thickness(0,180,0,0);
}
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
TheList.Margin = new Thickness();
}

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);
}
}
}