我正在嘗試在我的 Xamarin 應用程式中顯示一個帶有 DataTemplate 的專案,我可以使用什么 XAML 控制元件?
就我而言,我正在構建一個會議應用程式,并且正在嘗試顯示會議的所有者。
我嘗試使用 CollectionView(UserTemplate 是一個 DataTemplate):
<CollectionView
ItemsSource="{Binding Meeting.Owner}"
ItemTemplate="{StaticResource UserTemplate}"/>
但這沒有顯示任何內容,因為 CollectionView 僅支持專案串列(當我嘗試使用串列時它確實有效)。
我可以為單個專案使用什么替代方案?
用戶模板 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>
uj5u.com熱心網友回復:
我知道這可能不是一個完美的解決方案,但也許它會幫助你。
您可以使用 ContentView 來顯示您的資料,而不是模板。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, INotifyPropertyChanged
{
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
var changed = PropertyChanged;
if (changed == null)
return;
changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
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(),
propertyChanged: (bindable, oldVal , newVal) => ((UserView)bindable).OnPropertyChanged(nameof(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 屬性
uj5u.com熱心網友回復:
給定一個Meeting,包含一個屬性User,我們怎么能顯示DataTemplate的Meeting.User?
要使用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>
我已經展示了一個 inline DataTemplate,但這可以使用在別處定義的 DataTemplate :
<CollectionView ... ItemTemplate="{StaticResource YourTemplateName}"/>
以上回答使用的定義MainPageViewModel,Meeting以及User如下圖所示。
或 如果目標是在另一個屬性(會議)上顯示屬性(用戶)的詳細資訊,則可能根本不需要 DataTemplate。
This is a different goal than the question asked; this shows how to refer to "nested" properties such as "Meeting.User.Name".
Consider these models:
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 is optional; it is for use (later in development) of the convenience method OnPropertyChanged(nameof(SomeProperty));
And this view model:
public class MainPageViewModel : BindableObject
{
public Meeting Meeting { get; set; } = new Meeting();
}
Two possible approaches.
-1. Refer directly to "nested" properties. E.g. {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>
OR 2. Set a different "BindingContext" on parts of the XAML.
<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>
These two XAML snippets behave identically. Both display:
Description of meeting
Test User
Test SomeProperty
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/334653.html
標籤:xml 沙马林 xamarin.forms
上一篇:我如何實作像圓一樣的導航?
下一篇:在多個設備之間具有相同的控制寬度
