【问题标题】:UWP x:bind issue - Invalid binding path 'dpl' : Property 'dpl' not found on type 'DataTemplate'UWP x:绑定问题 - 无效的绑定路径“dpl”:在类型“DataTemplate”上找不到属性“dpl”
【发布时间】:2020-04-27 00:54:35
【问题描述】:

我有一个课程PricingDataPricingSchedule。其中PricingSchedulePricingData 类中的List。我想将此类的数据绑定到 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>

我想要实现的目标:组合框应填充值列表(例如 1USD、2USD、3USD 等)。然后,当您提供数据库中的记录列表时,列表框将重复 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在类型 'DataTemplate' 上找到。”

我想知道为什么 x:bind dpl 在这一点上不起作用。 ?

【问题讨论】:

    标签: c# uwp uwp-xaml


    【解决方案1】:

    我现在意识到您的问题实际上是您需要从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 指定控件的各个项目将具有的数据类型。假设您的 PricingScheduleListList&lt;MyApp.Models.MyType&gt;,那么您首先需要将此 XML 命名空间添加到 &lt;Page&gt; 元素:

    xmlns:models="using:MyApp.Models"
    

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

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

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

    【讨论】:

    • 嗨 Martin Zikmund,我已经用你的建议 ItemsSource="{Binding ElementName=UCpage, Path=dpl}" 更新了 GitHub url 上的源代码,但它仍然使用值列表填充组合框。可以请你看看和指导。
    • 当我检查你的最新项目时,名为“cbSchedulePriceValueList”的组合框可以成功显示值列表,效果很好,那么你当前的问题是什么,你能详细说明一下吗?跨度>
    • 嗨 Faywang,我更新了代码,也许你已经看到了最新的提交,但是如果你检查以前的提交,它不会按照 Martin Z 的建议工作。在最新的 cmets 中它可以工作,因为我已经修改了代码一种不同的方式。我创建了一个资源 并在绑定 x:Name 中使用了它="cbSchedulePriceValueList" ItemsSource="{Binding Source={StaticResource myList}}"。这种方法奏效了。
    • 但问题仍然是以下两个语句都不起作用 SelectedItem="{Binding DisplayPricing,Mode=TwoWay}" SelectedValue="{Binding DisplayPricing,Mode=TwoWay}" 你能说明一下吗是吗?
    【解决方案2】:

    通过检查您的代码,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}" />
    

    【讨论】:

      猜你喜欢
      • 2020-11-08
      • 2018-05-15
      • 2021-12-07
      • 2017-07-20
      • 2020-11-05
      • 2019-09-29
      • 2021-01-13
      • 2017-02-21
      • 2020-02-01
      相关资源
      最近更新 更多