更新时间:2023-11-12 13:28:40
Since you had used Data-Binding , it would be better to handle logic (fill data and navigation) in ViewModel and use Command instead of Click Event .
Also, I'm interested in moving as much logic to the xaml files
I couldn't get the same functionality to work with a listview, which I would prefer.
So you could modify and improve the code like following . I used ListView to display the data .
using CustomViewListTest.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace CustomViewListTest.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PersonCard : ContentView
{
public PersonCard()
{
InitializeComponent();
}
public static readonly BindableProperty NameProperty =
BindableProperty.Create(nameof(Name), typeof(string), typeof(PersonCard), string.Empty);
public static readonly BindableProperty AgeProperty =
BindableProperty.Create(nameof(Age), typeof(string), typeof(PersonCard), string.Empty);
public string Name
{
get => (string)GetValue(NameProperty);
set => SetValue(NameProperty, value);
}
public string Age
{
get => (string)GetValue(AgeProperty);
set => SetValue(AgeProperty, value);
}
public static readonly BindableProperty ClickCommandProperty =
BindableProperty.Create(nameof(ClickCommand), typeof(ICommand), typeof(PersonCard));
public ICommand ClickCommand
{
get => (ICommand)GetValue(ClickCommandProperty);
set => SetValue(ClickCommandProperty, value);
}
public static BindableProperty ClickParameterProperty =
BindableProperty.Create(nameof(ClickParameter), typeof(object), typeof(PersonCard));
public object ClickParameter
{
get => (object)GetValue(ClickParameterProperty);
set => SetValue(ClickParameterProperty, value);
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CustomViewListTest.Views.PersonCard"
xmlns:System="clr-namespace:System;assembly=mscorlib"
x:Name="card"
>
<ContentView.Content>
<Frame BorderColor="#3F3F3F" Padding="0" Margin="2">
<Frame.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ClickCommand,Source={x:Reference card}}" CommandParameter="{Binding ClickParameter,Source={x:Reference card}}"/>
</Frame.GestureRecognizers>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Name,Source={x:Reference card}}" TextColor="Red"></Label>
<Label Text="{Binding Age,Source={x:Reference card}}" TextColor="Green"></Label>
</StackLayout>
</Frame>
</ContentView.Content>
</ContentView>
using CustomViewListTest.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Windows.Input;
namespace CustomViewListTest.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PersonList : ContentPage
{
public PersonList()
{
InitializeComponent();
BindingContext = new MyViewModel(this.Navigation);
}
}
public class MyViewModel
{
public ICommand ClickCommand { get; private set; }
INavigation CurrentNavigation;
public ObservableCollection<Person> MyItems {get;set;}
public MyViewModel( INavigation navigation)
{
CurrentNavigation = navigation;
MyItems = new ObservableCollection<Person>() { new Person("Jack",23),new Person("Lucas",25) };
ClickCommand = new Command(async (org) =>
{
var item = org as Person;
PersonFullView page = new PersonFullView(item);
await CurrentNavigation.PushAsync(page);
});
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CustomViewListTest.Views.PersonList"
xmlns:views ="clr-namespace:CustomViewListTest.Views"
x:Name="page"
>
<StackLayout>
<ListView ItemsSource="{Binding MyItems}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<views:PersonCard Name="{Binding Name}" Age="{Binding Age}" ClickCommand="{Binding Path=BindingContext.ClickCommand,Source={x:Reference page}}" ClickParameter="{Binding .}" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
MainPage = new NavigationPage(new PersonList());