代码之家  ›  专栏  ›  技术社区  ›  slayernoah

在GridView数据模板内的组合框中填充组合框项目和SelectedValue

  •  0
  • slayernoah  · 技术社区  · 7 年前

    我正在开发一个Windows 10通用应用程序,在GridView数据模板中的组合框(组合框项目和SelectedValue)中填充项目时遇到问题。我似乎找不到这样做的方法。

    详情如下:

    我有个目标( UserData )可以包含另一个对象的多个实例的( List<VisitedCity> ). 在XAML页面上,的多个实例 VisitedCity 显示在垂直网格视图上。

    的每个实例 访问城市 可以包含 CityName VisitedDate . 在XAML页面上,CityName显示在组合框中,访问日期显示在每个GridViewItem内的日期选择器上。

    什么不起作用:

    显示每个访问城市的选定城市名称的组合框需要从 List<string> 变量(以便用户可以更改)和组合框SelectedValue需要从curretUserData对象的 VisitedCities 属性(CityName属性)。

    我正在尝试使用 x:Bind 在XAML上,以最小化代码落后。

    我已经包含了我为解决此问题而使用的示例应用程序中的所有代码,并且还指出了我在XAML上遇到问题的代码行。

    请注意,这是以VisitedCities为例的大型应用程序的高度简化部分,以便更好地演示问题。感谢您的帮助和投入!

    这是我的班级档案:

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

    这是我的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>
    

    下面是我的代码:

    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);
            }
        }
    }
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Michael Hawker - MSFT    7 年前

    您需要修改绑定表达式以从父页面获取。x: Bind将只使用本地DataContext,在本例中,它是模板化的项。

    <ComboBox Grid.Column="0" x:Name="myTemplateComboBox"  ItemsSource="{Binding ElementName=MyPage, Path=CityList }" SelectedValue="{x:Bind CityName, Mode=TwoWay}" HorizontalAlignment="Stretch"  />
    

    在本例中,我将CityList设置为公共属性,然后命名页面,以便使用 ElementName .

    您还需要启用 TwoWay 绑定,以便在用户进行更改后将值设置回数据模型。

    如果使用可观察的集合而不是列表,那么可以通过修改数据模型将行添加到GridView中。我遇到了一个例外。

    我还将初始用户名替换为占位符文本,这样用户就不必为了键入自己的名称而删除示例名称。

    完整代码

    <Page
        x:Class="SOCityGridView.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:SOCityGridView"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        x:Name="MyPage"
        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 currentUserData.FullName}" PlaceholderText="Sample User"/>
    
            <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 currentUserData.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="{Binding ElementName=MyPage, Path=CityList }" SelectedValue="{x:Bind CityName, Mode=TwoWay}" HorizontalAlignment="Stretch"  />
    
                            <DatePicker Grid.Column="1" x:Name="myTemplateDatePicker" Date="{x:Bind VisitedDate, Mode=TwoWay}" />
    
                        </Grid>
                    </DataTemplate>
                </GridView.ItemTemplate>
            </GridView>
        </Grid>
    </Page>
    

    和代码隐藏:

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    
    // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
    
    namespace SOCityGridView
    {
        /// <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 currentUserData = new UserData();
            public List<string> CityList { get; set; } = 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
                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") });
                currentUserData.VisitedCities = new ObservableCollection<VisitedCity>(sampleUserVisitedCities);
    
                this.InitializeComponent();
            }
    
            private void myButton_Click(object sender, RoutedEventArgs e)
            {
                currentUserData.VisitedCities.Add(new VisitedCity { CityName = "City1", VisitedDate = DateTime.Now });
            }
        }
    
        public class UserData
        {
            public string FullName { get; set; }
            public ObservableCollection<VisitedCity> VisitedCities { get; set; }
        }
    
        public class VisitedCity
        {
            public string CityName { get; set; }
            public DateTimeOffset VisitedDate { get; set; }
    
        }
    
        public 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;
    
            }
        }
    }