属性 在 UWP 应用的 ViewModel 上找不到

Property can't be found on ViewModel in UWP app

UWP 中使用模板 10 的订单将产品添加到订单。错误是

Invalid binding path 'OrderViewModel.FindProduct_TextChanged' : Property 'OrderViewModel' can't be found on type 'ProductViewModel'

相关的 xaml 片段是

<Page.DataContext>
    <ViewModels:MainPageViewModel x:Name="OrderViewModel" />
</Page.DataContext>

<GridView  ItemsSource="{x:Bind OrderViewModel.Products, Mode=TwoWay}">
    <GridView.ItemTemplate>
        <DataTemplate x:DataType="ViewModels:ProductViewModel" >
            <AutoSuggestBox 
                Name="ProductAutoSuggestBox" 
                TextMemberPath="{x:Bind ItemCode, Mode=TwoWay}"
                TextChanged="{x:Bind OrderViewModel.FindProduct_TextChanged}">
            </AutoSuggestBox>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

OrderViewModel 和 ProductViewModel 的相关片段

namespace ViewModels
{    
    public class OrderViewModel : ViewModelBase
    {
        public ObservableCollection<Product> Products { get; set; } = new ObservableCollection<Product>();

        public void FindProduct_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
        { ... }
    }

    public class ProductViewModel : ViewModelBase
    {
        string _ItemCode = default(string);
        public string ItemCode { get { return _ItemCode; } set { Set(ref _ItemCode, value); } }

        public ProductViewModel()
        {
        }
    }
}

如何从引用 ProductViewModel 的 GridView 的数据模板中正确引用 OrderViewModel 上的 FindProduct_TextChanged

对@tao 的评论投了赞成票。 @Vague,我想你可能误解了 x:DataType 的用途。可以参考Data binding in depth的"DataTemplate and x:DataType"部分:

When using {x:Bind} in a data template, so that its bindings can be validated (and efficient code generated for them) at compile-time, the DataTemplate needs to declare the type of its data object using x:DataType.

对于您的场景,根据您的代码 public ObservableCollection<Product> Products { get; set; } = new ObservableCollection<Product>();,您的 DataTemplate 数据对象的类型应该是您的 Product class,而不是您的 [=15] =],同时,你的 FindProduct_TextChanged 事件必须在这个 Product class 中找到,这意味着你的 FindProduct_TextChanged 代码应该放在你的 Product ] 数据模型。

顺便说一句,我认为没有必要为ItemsSource使用TwoWay绑定。对于这种情况,绑定目标是 GridViewItemsSource,绑定源是 ObservableCollection<Product> Products,我知道你想在你的集合更新时更新 GridView,这是工作用 ObservableCollection 完成。另外这里只能更改绑定源来通知绑定目标,所以OneWay绑定就可以了。不过你的代码问题不大。

所以对于你的GridView,它应该是这样的:

<GridView  ItemsSource="{x:Bind OrderViewModel.Products, Mode=OneWay}">
    <GridView.ItemTemplate>
        <DataTemplate x:DataType="Models:Product" >
            <AutoSuggestBox 
                Name="ProductAutoSuggestBox" 
                TextMemberPath="{x:Bind ItemCode, Mode=TwoWay}"
                TextChanged="{x:Bind FindProduct_TextChanged}">
            </AutoSuggestBox>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

如果错误有点像这样,我批准它是一个字符集支持错误: 错误无效绑定路径 'XX.YY':属性 'ZZ' 无法在类型 'CCC'

上找到

xaml和C#支持unicode; 这是因为您在 class 属性中使用了非 ascii 字符。这是我今天发现的一个错误。只需将 class proprty 字符重命名为 ascii 标准。希望能修复。