UWP x:bind 问题 - 绑定路径无效 'dpl':属性 'dpl' 未在类型 'DataTemplate' 上找到

UWP x:bind issue - Invalid binding path 'dpl' : Property 'dpl' not found on type 'DataTemplate'

我有一个 class PricingDataPricingSchedule。其中 PricingSchedulePricingData class 中的列表<>。我想将此 class 的数据绑定到 UWP 控件。

示例代码可在此处下载:https://github.com/jigneshdesai/SampleOfBindingIssue1.git

代码的外观: 我有一个托管 ListView 控件的起始页(主页),Listview 中有 PricingUserControl。 PricingUserControl 看起来像这样

<TextBlock x:Name="lblPriceHeader" Text="{Binding PricingTitle}" Margin="0,0,50,0" />
            <ComboBox  x:Name="cbPriceValueList" ItemsSource="{x:Bind dpl}" DisplayMemberPath="PriceValue" SelectedValuePath="PriceValue"  SelectedValue="{Binding DisplayPricing}"   />

            <ListView x:Name="lbPriceChangeSchedule" ItemsSource="{Binding PricingScheduleList}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <StackPanel Orientation="Horizontal">
                                <ComboBox  x:Name="cbSchedulePriceValueList"  ItemsSource="{x:Bind dpl}" DisplayMemberPath="PriceValue" SelectedValuePath="PriceValue"  />

                                <TextBlock Text="{Binding SchedulePricingTimeZone }" />
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

我想要实现的目标:组合框应填充一个值列表(例如 1 美元、2 美元、3 美元等)。然后,当您提供数据库中的记录列表时,列表框将重复 PricingUserControl,其中的组合框应根据记录设置其值 属性 (SelectedValue)。

问题: ComboBox x:Name="cbPriceValueList" 使用 x:bind dpl 其中 dpl 是 PricingUserControl 的局部变量。它会正确填充列表。问题是 ComboBox x:Name="cbSchedulePriceValueList" 它也有 x:bind dpl 但在编译期间它显示错误 "Invalid binding path 'dpl' : Property 'dpl' not found on type 'DataTemplate'."

我想知道为什么 x:bind dpl 此时不起作用。 ?

我现在意识到你的问题实际上是你需要从 DataTemplate 中到达 Page 属性,所以这里是更新的答案。

如果您需要从 DataTemplate 中访问外部元素的 属性,则不能使用 x:Bind。相反,您可以使用经典的 {Binding} 表达式。首先为您的页面添加名称:

<Page
   ...
   x:Name="Page">

现在从 DataTemplate:

中引用这个名字
<ComboBox  
     x:Name="cbSchedulePriceValueList"  
     ItemsSource="{Binding ElementName=Page, Path=dpl}" 
     DisplayMemberPath="PriceValue" 
     SelectedValuePath="PriceValue"  />

原回答

为了能够在 DataTemplate 中使用 x:Bind,您必须使用 x:DataType 指定控件的各个项目将具有的数据类型。假设你的 PricingScheduleList 是一个 List<MyApp.Models.MyType>,那么你首先需要将这个 XML 命名空间添加到 <Page> 元素:

xmlns:models="using:MyApp.Models"

然后设置x:DataType属性如下:

<DataTemplate x:DataType="models:MyType">
    ...
</DataTemplate>

当您开始编写 x:Bind 表达式时,IntelliSense 现在应该向您建议 MyType 的属性,您可以确认这是否有效。

查看你的代码,SelectedValue不生效的原因是你在ComboBox中选择项目时,没有通知你的DisplayPricing改变。因此,您需要在 PricingData 中实现 INotifyPropertyChanged 接口。在 PricingSchedule 中执行相同的操作。

public class PricingData : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged = delegate { };
        ......

        public string DisplayPricing
        {
            get => $"{PricingValue} {PricingCurrency}";
            set
            {
                var sp = value.Split(' ');
                PricingValue = sp.First();
                PricingCurrency = sp.Last();
                OnPropertyChanged();
            }
        }

        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    } 

PScheduleUserControl.xaml:

<ComboBox  x:Name="cbPriceValueList" ItemsSource="{x:Bind myList}" DisplayMemberPath="PriceValue" SelectedValuePath="PriceValue"  SelectedValue="{Binding DisplayPricing,Mode=TwoWay}" />