绑定到 ObservableCollection<Tuple<string,string>> 导致错误 XFC0045 绑定:属性 "Item1" 未找到
Binding to ObservableCollection<Tuple<string,string>> results in Error XFC0045 Binding: Property "Item1" not found
我有一个 ObservableCollection>。我想将这个字符串从不同的元组绑定到我的前端。
启动模拟器时,出现如下错误:错误 XFC0045 绑定:属性“Item1”未找到。
.xaml
<ScrollView>
<CollectionView x:Name="ItemsListView" ItemsSource="{Binding ResultCollection}" SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<!-- Item 1 = UserAnswer -->
<Label Style="{StaticResource SubItem}" Text="{Binding Item1}"/>
<!-- Item 2 = CorrectAnswer -->
<Label Style="{StaticResource SubItem}" Text="{Binding Item2}"/>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ScrollView>
ViewModel
UserAnswers 和 CorrectAnswers 都是 List.
ResultCollection = new ObservableCollection<Tuple<string, string>>();
for(int i = 0; i < UserAnswers.Count; i++)
{
ResultCollection.Add(new Tuple<string, string>(UserAnswers[i], CorrectAnswers[i]));
}
谁能帮我在我的 .xaml 中绑定这个元组?
来自 docs
C# tuples, which are backed by System.ValueTuple types, are different
from tuples that are represented by System.Tuple types. The main
differences are as follows:
- ValueTuple types are value types. Tuple types are reference types.
- ValueTuple types are mutable. Tuple types are immutable.
- Data members of ValueTuple types are fields. Data members of Tuple types are properties.
您只能绑定到 public 属性,因此绑定仅适用于 System.Tuple
您可能在页面前面有一个 x:DataType
。鉴于此,要使绑定在 CollectionView 内部起作用,您还需要在 ItemTemplate 或 DataTemplate 上有一个 x:DataType
语句,指定其类型。
但如果绑定数据涉及通用类型 (...<...>
),则不能。
这是 XAML 中 x:DataType
声明的限制。
见Enhancement Allow generics in x:DataType。
修复 #1:
- 删除 XAML 文件中的所有
x:DataType
语句。
PRO:XF 会在 运行 时弄清楚要做什么。无需进一步更改您的代码即可正常工作。
缺点:如果集合中的项目很多,可能会出现性能问题。
修复#2:
为您的项目定义一个具有属性的自定义 class。在 ItemTemplate 的 DataTemplate 的 x:DataType
中使用 class 名称。
MyTuple.cs:
public class MyTuple : Tuple<string, string>
{
public MyTuple(string item1, string item2) : base(item1, item2)
{
}
}
MyContentPage.xaml:
<ContentPage ...
xmlns:local="clr-namespace:YourNamespaceHere" <-- replace YourNamespaceHere
...>
...
<CollectionView ...
...
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="local:MyTuple">
...
.cs:
public ObservableCollection<MyTuple> ResultCollection { get; set; }
private void Init()
{
ResultCollection = new ObservableCollection<MyTuple> {
new MyTuple("a", "abcabc")
};
}
1.Set 你的 ResultCollection
属性 到 public.
2.Set 您后台代码中的 BindingContext
。
3.Since 你设置 x:name
。您还可以在后台代码中使用类似的代码:ItemsListView.ItemsSource = ResultCollection;
我写了一个小例子供大家参考。
这里是后台代码(xaml代码与你提供的一致):
public partial class MainPage : ContentPage
{
public ObservableCollection<Tuple<string, string>> ResultCollection { get; set; }//Set public
public MainPage()
{
InitializeComponent();
ResultCollection = new ObservableCollection<Tuple<string, string>>();
for (int i = 0; i < 5; i++)
{
ResultCollection.Add(new Tuple<string, string>(i.ToString(), i.ToString()));
}
BindingContext = this;// Set BindingContext
}
}
我有一个 ObservableCollection
启动模拟器时,出现如下错误:错误 XFC0045 绑定:属性“Item1”未找到。
.xaml
<ScrollView>
<CollectionView x:Name="ItemsListView" ItemsSource="{Binding ResultCollection}" SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<!-- Item 1 = UserAnswer -->
<Label Style="{StaticResource SubItem}" Text="{Binding Item1}"/>
<!-- Item 2 = CorrectAnswer -->
<Label Style="{StaticResource SubItem}" Text="{Binding Item2}"/>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ScrollView>
ViewModel UserAnswers 和 CorrectAnswers 都是 List.
ResultCollection = new ObservableCollection<Tuple<string, string>>();
for(int i = 0; i < UserAnswers.Count; i++)
{
ResultCollection.Add(new Tuple<string, string>(UserAnswers[i], CorrectAnswers[i]));
}
谁能帮我在我的 .xaml 中绑定这个元组?
来自 docs
C# tuples, which are backed by System.ValueTuple types, are different from tuples that are represented by System.Tuple types. The main differences are as follows:
- ValueTuple types are value types. Tuple types are reference types.
- ValueTuple types are mutable. Tuple types are immutable.
- Data members of ValueTuple types are fields. Data members of Tuple types are properties.
您只能绑定到 public 属性,因此绑定仅适用于 System.Tuple
您可能在页面前面有一个 x:DataType
。鉴于此,要使绑定在 CollectionView 内部起作用,您还需要在 ItemTemplate 或 DataTemplate 上有一个 x:DataType
语句,指定其类型。
但如果绑定数据涉及通用类型 (...<...>
),则不能。
这是 XAML 中 x:DataType
声明的限制。
见Enhancement Allow generics in x:DataType。
修复 #1:
- 删除 XAML 文件中的所有
x:DataType
语句。
PRO:XF 会在 运行 时弄清楚要做什么。无需进一步更改您的代码即可正常工作。
缺点:如果集合中的项目很多,可能会出现性能问题。
修复#2:
为您的项目定义一个具有属性的自定义 class。在 ItemTemplate 的 DataTemplate 的 x:DataType
中使用 class 名称。
MyTuple.cs:
public class MyTuple : Tuple<string, string>
{
public MyTuple(string item1, string item2) : base(item1, item2)
{
}
}
MyContentPage.xaml:
<ContentPage ...
xmlns:local="clr-namespace:YourNamespaceHere" <-- replace YourNamespaceHere
...>
...
<CollectionView ...
...
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="local:MyTuple">
...
.cs:
public ObservableCollection<MyTuple> ResultCollection { get; set; }
private void Init()
{
ResultCollection = new ObservableCollection<MyTuple> {
new MyTuple("a", "abcabc")
};
}
1.Set 你的 ResultCollection
属性 到 public.
2.Set 您后台代码中的 BindingContext
。
3.Since 你设置 x:name
。您还可以在后台代码中使用类似的代码:ItemsListView.ItemsSource = ResultCollection;
我写了一个小例子供大家参考。
这里是后台代码(xaml代码与你提供的一致):
public partial class MainPage : ContentPage
{
public ObservableCollection<Tuple<string, string>> ResultCollection { get; set; }//Set public
public MainPage()
{
InitializeComponent();
ResultCollection = new ObservableCollection<Tuple<string, string>>();
for (int i = 0; i < 5; i++)
{
ResultCollection.Add(new Tuple<string, string>(i.ToString(), i.ToString()));
}
BindingContext = this;// Set BindingContext
}
}