WinUI 3 ComboBox ItemsSource 绑定字典<string, CustomClassObject> 抛出 InvalidOperationException“目标类型不是投影类型”

问题描述 投票:0回答:1

描述错误

ComboBox

 是类对象时,
ItemsSource
Dictionary<TKey,TValue>
TValue
绑定会引发错误。

我的项目使用 WinUI 3 和 C#。

我查看了许多其他类似的帖子,讨论了

ComboBox
ItemsSource
Dictionary<TKey,TValue>
的绑定,我很确定我做的一切都是正确的。 我什至通过使用
Dictionary<string,int>
对象绑定到
ComboBox
来测试代码,并且它可以正常工作。

但只有当我使用类对象作为

TValue
时,它才会抛出此错误:

Exception thrown: 'System.InvalidOperationException' in WinRT.Runtime.dll
Target type is not a projected type: App1.Sample

并且调试器显示问题发生在

obj.ItemsSource = value;
中:

public static void Set_Microsoft_UI_Xaml_Controls_ItemsControl_ItemsSource(global::Microsoft.UI.Xaml.Controls.ItemsControl obj, global::System.Object value, string targetNullValue)
{
    if (value == null && targetNullValue != null)
    {
        value = (global::System.Object) global::Microsoft.UI.Xaml.Markup.XamlBindingHelper.ConvertValue(typeof(global::System.Object), targetNullValue);
    }
    obj.ItemsSource = value;
}
...

我试图找到讨论此错误的帖子,但没有得到任何解决方案。

重现错误的步骤

  1. 在 Visual Studio 中创建一个新的空白应用程序,打包(桌面中的 WinUI 3)
  2. 相应添加以下代码:

MainWindow.xaml

<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Class="App1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <ComboBox ItemsSource="{x:Bind Samples}"
                  DisplayMemberPath="Key"
                  SelectedValuePath="Value"></ComboBox>
    </StackPanel>
</Window>

MainWindow.xaml.cs

using Microsoft.UI.Xaml;
using System.Collections.Generic;

namespace App1 {
    public sealed partial class MainWindow : Window {
        public MainWindow() {
            this.InitializeComponent();
            Samples.Add("skdn", new());
        }

        public Dictionary<string, Sample> Samples = new();

        public class Sample {
            public string Name { get; set; }
            public Sample() {

            }
        }
    }
}
  1. 运行应用程序

预期行为

应用程序应该运行没有错误。

c# dictionary xaml winui-3
1个回答
0
投票

我知道这个问题发布在这里已经有几个月了,这可能只是一个类似的问题,但我想分享我最近的经验。

我在使用 CommunityToolkit.Mvvm 包的 WinUI 3 应用程序中遇到了问题。错误消息是

源对象类型不是投影类型,并且不继承自投影类型。

我有一个视图模型类和一个数据模板,用于显示视图模型中的数据。

经过一些搜索和代码检查,我注意到数据模板的目标类型和视图模型类之间不匹配。

为了说明问题,我的视图模型类如下。

namespace MyApplication.WinUI3Client.ViewModels;

public partial class FeedViewModel : ObservableRecipient
{
    [ObservableProperty] private Guid _id;
    // ... the rest of the class
}

但是,我的 XAML 数据模板类似于以下内容。

<DataTemplate x:Key="FeedItemTemplate" x:DataType="viewModels:FeedsViewModel">
    <Grid>
        <!-- The content of the data template -->
    </Grid>
</DataTemplate>

请注意类名称

FeedViewModel
和数据模板
x:DataType="viewModels:FeedsViewModel"
的目标类型(Feed 与 Feed)之间的差异,后者实际上是包含各个 Feed 的父视图模型。纠正错误后,一切又开始工作了。

所以看看你的代码,我怀疑问题出在字典作为键值对的 IEnumerable 的内部表示中。我会尝试将项目源的目标模型更改为自定义实现。它将把字典中示例的键和示例本身封装在一个类或类似的类中以满足您的需求。 当尝试您建议的重现问题的方法时,我遇到了问题

System.Reflection.TargetInitationException:调用目标已引发异常。

System.TypeInitializationException:“ABI.System.Collections.Generic.KeyValuePair`2”的类型初始值设定项引发异常。

也许是因为它没有无参构造函数。没有把握。调试起来相当有深度。但是,我会避免使用像

Dictionary<TKey, TValue>
这样的“映射”类型作为项目源,并创建包含在
ObservableCollection<T>
中的可行的自定义表示。

© www.soinside.com 2019 - 2024. All rights reserved.