且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

何时使用 Xamarin 绑定而不是将对象传递给页面构造函数?

更新时间: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 .

in PersonCard

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>

in PersonList

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>

in App

MainPage = new NavigationPage(new PersonList());