I am developing a Windows 10 Universal App and I have trouble getting items to populate in a ComboBox (both ComboBox items and SelectedValue) that is within a GridView DataTemplate. I don't seem to be able to find a way to do this.
Here are the details:
I have an object (UserData
) that can contain multiple instances of another object (List<VisitedCity>
). On the XAML page, the multiple instances of VisitedCity
are shown on a vertical GridView.
Each instance of VisitedCity
can contain the CityName
and VisitedDate
. On the XAML page, the CityName is to be shown on a ComboBox and the visited date on a Date on a DatePicker inside each GridViewItem.
What doesn't work:
The ComboBox showing the selected city name of each VisitedCity needs to have it's list of items on it loaded from a List<string>
variable (so that the user can change it) and the ComboBox SelectedValue needs to be loaded from the curretUserData object's VisitedCities
property (CityName property).
I an trying to do this using x:Bind
on the XAML in order to minimize the code behind.
I have included all my code from the sample app I did to troubleshoot this and I have also indicated the line of code on the XAML that I am having issues with.
Please note, this is highly simplified part of a larger app with VisistedCities as an example so that the problem can be demonstrated better. Thank you for all your help and input!
Here is my class file:
namespace mySampleApp
{
class UserData
{
public string FullName { get; set; }
public List<VisitedCity> VisitedCities { get; set; }
}
class VisitedCity
{
public string CityName { get; set; }
public DateTime VisitedDate { get; set; }
}
class CityNameManager
{
public static List<string> GetListOfCitiesFromServer()
{
List<string> listOfCities = new List<string>();
//code will be here to get the latest list from the server. for now we will manually return a list
listOfCities.Add("City1");
listOfCities.Add("City2");
listOfCities.Add("City3");
listOfCities.Add("City4");
listOfCities.Add("City5");
return listOfCities;
}
}
}
Here is my XAML:
<Page
x:Class="mySampleApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:mySampleApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox x:Name="txtFirstName" Grid.Row="0" Header="Enter Your Name" Text="{x:Bind curretUserData.FullName}"/>
<TextBlock x:Name="label1" Grid.Row="1" TextWrapping="WrapWholeWords" Text="Please select all cities you have visited during the last 5 years. For each city please enter the data visited. If you visited a city multiple times, please have multiple entries for each time indicating the date visited each time." />
<TextBlock x:Name="label2" Grid.Row="2" TextWrapping="WrapWholeWords" Text="Press the + button to add rows as needed. " />
<Button x:Name="myButton" Grid.Row="3" Content="+" Click="myButton_Click" />
<GridView x:Name="myGridView" Grid.Row="4" HorizontalContentAlignment="Stretch" SelectionMode="None" ItemsSource="{x:Bind curretUserData.VisitedCities}">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:VisitedCity">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- This is the line of code which has issues-->
<ComboBox Grid.Column="0" x:Name="myTemplateComboBox" ItemsSource="{local:CityList ??? }" SelectedValue="{x:Bind CityName ??? }" HorizontalAlignment="Stretch" />
<DatePicker Grid.Column="1" x:Name="myTemplateDatePicker" Date="{x:Bind VisitedDate }" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
</Page>
Here is my code behind:
namespace mySampleApp
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
//variables to use in XAML x:Bind
private UserData curretUserData = new UserData();
private List<string> CityList = new List<string>();
public MainPage()
{
//get latest list of cities from the server
CityList = CityNameManager.GetListOfCitiesFromServer();
//add sample data to show on the page for demo
curretUserData.FullName = "Sample User";
List<VisitedCity> sampleUserVisitedCities = new List<VisitedCity>();
sampleUserVisitedCities.Add(new VisitedCity {CityName = "City1", VisitedDate=DateTime.Parse("2/2/2016") });
sampleUserVisitedCities.Add(new VisitedCity {CityName = "City2", VisitedDate = DateTime.Parse("2/2/2015") });
curretUserData.VisitedCities = sampleUserVisitedCities;
this.InitializeComponent();
}
private void myButton_Click(object sender, RoutedEventArgs e)
{
//add a new row
GridViewItem gridViewItem = new GridViewItem();
gridViewItem.ContentTemplate = myGridView.ItemTemplate;
myGridView.Items.Add(gridViewItem);
}
}
}