我想显示一个项目与DataTemplate在我的Xamarin应用程序,我可以使用什么XAML控件?
在我的情况下,我正在建立一个会议应用程序,我正试图显示会议的所有者。
我尝试使用CollectionView (UserTemplate是一个DataTemplate):
<CollectionView
ItemsSource="{Binding Meeting.Owner}"
ItemTemplate="{StaticResource UserTemplate}"/>
,但这并没有显示任何东西,因为CollectionView只支持项目列表(当我试图使用列表时,它真的很有效)。
对于单个条目,我可以使用什么替代方案?
UserTemplate XAML:
<DataTemplate x:Key="UserTemplate">
<Grid Padding="10"
RowDefinitions="Auto,Auto"
ColumnDefinitions="Auto,Auto">
<Image Grid.RowSpan="2"
Source="{Binding IconURL}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding age}"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</DataTemplate>
我知道这可能不是一个完美的解决方案,但它可能会帮助你。
你可以用ContentView代替Template来显示你的数据。它的XML看起来几乎与您的模板相似。
XAML:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:models="clr-namespace:TestAppNew.Models"
x:Class="TestAppNew.Views.UserView"
x:Name="View">
<Frame BindingContext="{Binding Source={x:Reference View}, Path=User}"
x:DataType="models:User">
<Grid Padding="10"
RowDefinitions="Auto,Auto"
ColumnDefinitions="Auto,Auto">
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding age}"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</Frame>
</ContentView>
背后的代码:
public partial class UserView : ContentView
{
public User User
{
get => (User)GetValue(UserProperty);
set => SetValue(UserProperty, value);
}
public static readonly BindableProperty UserProperty =
BindableProperty.Create("User", typeof(User), typeof(UserView), new User());
public UserView()
{
InitializeComponent();
}
}
现在你可以在代码中使用这个视图了。
单项目:
<views:UserView User="{Binding Meeting.Owner}" />
或多个:
<CollectionView ItemsSource="{Binding Meetings}">
<CollectionView.ItemTemplate>
<DataTemplate>
<views:UserView User="{Binding Owner}" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
不做进一步的研究,我认为你应该能够包装这个视图在一个额外的DataTemplate,这样你仍然可以访问ListView或CollectionView的直接ItemTemplate属性
给定一个包含属性User
的Meeting
,如何显示Meeting.User
的DataTemplate
?
要使用CollectionView
,我们需要一个List<User>
。一种解决方案是创建一个"值转换器":
using System;
using System.Collections.Generic;
using System.Globalization;
using Xamarin.Forms;
namespace BindSubView
{
/// <summary>
/// Given a single object, return a list containing just that object.
/// </summary>
public class OneItemListConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return new List<object> { value };
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
使用例子:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:BindSubView"
x:Class="BindSubView.MainPage">
<ContentPage.BindingContext>
<local:MainPageViewModel/>
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<local:OneItemListConverter x:Key="oneItemList" />
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<CollectionView ItemsSource="{Binding Meeting.User, Converter={StaticResource oneItemList}}" HeightRequest="100">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding Name}"/>
<Label Text="{Binding SomeProperty}"/>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage>
我已经展示了一个内联的DataTemplate
,但是它可以使用在其他地方定义的DataTemplate:
<CollectionView ... ItemTemplate="{StaticResource YourTemplateName}"/>
上面的答案使用了MainPageViewModel
、Meeting
和User
的定义,如下所示。
OR如果目标是在另一个属性(Meeting)上显示属性(User)的详细信息,可能根本不需要DataTemplate。
这是一个不同于所问问题的目标;这展示了如何引用"嵌套的"。如"meeting . user . name"等属性
考虑这些模型:
using Xamarin.Forms;
namespace BindSubView
{
public class Meeting : BindableObject
{
public string Description { get; set; } = "Description of meeting";
public User User { get; set; } = new User();
}
public class User : BindableObject
{
public string Name { get; set; } = "Test User";
public string SomeProperty { get; set; } = "Test SomeProperty";
}
}
: BindableObject
是可选的;它是为了方便方法OnPropertyChanged(nameof(SomeProperty));
的使用(在以后的开发中)。这个视图模型:
public class MainPageViewModel : BindableObject
{
public Meeting Meeting { get; set; } = new Meeting();
}
两种可能的方法。
1。直接参考"嵌套"。属性。例:{Binding Meeting.User.Name}
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:BindSubView"
x:Class="BindSubView.MainPage">
<ContentPage.BindingContext>
<local:MainPageViewModel/>
</ContentPage.BindingContext>
<StackLayout>
<Label Text="{Binding Meeting.Description}"/>
<StackLayout>
<Label Text="{Binding Meeting.User.Name}"/>
<Label Text="{Binding Meeting.User.SomeProperty}"/>
</StackLayout>
</StackLayout>
</ContentPage>
或2。设置一个不同的& indingcontext ">
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:BindSubView"
x:Class="BindSubView.MainPage">
<ContentPage.BindingContext>
<local:MainPageViewModel/>
</ContentPage.BindingContext>
<!-- "Meeting" refers to a Property on the enclosing BindingContext. Here it means "MainPageViewModel.Meeting". -->
<StackLayout BindingContext="{Binding Meeting}">
<Label Text="{Binding Description}"/>
<!-- "User" refers to a Property on the enclosing BindingContext. Here it means "MainPageViewModel.Meeting.User". -->
<StackLayout BindingContext="{Binding User}">
<Label Text="{Binding Name}"/>
<Label Text="{Binding SomeProperty}"/>
</StackLayout>
</StackLayout>
</ContentPage>
这两个XAML代码段的行为相同。都显示:
Description of meeting
Test User
Test SomeProperty