微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

试图创建一个继承父类和调用的控件模板?

如何解决试图创建一个继承父类和调用的控件模板?

我正在尝试为我的 Xamarin.Forms 项目中的表单制作模板。 我想使用 SyncFusion SfCarousel 控件,并且由于我在许多表单上重用它,我想制作一个 xaml 视图,我可以在目标表单上实例化该视图,而不必每次都重新创建控件.

这是问题所在,我有 TapGestureRecognizer.OnTapped 和其他几个传递给此控件的 Data 对象。 以下是此次实施的示例。

....
            <DataTemplate x:Key="CarouselitemTemplate">
                <StackLayout Orientation="Vertical">
                    <StackLayout.GestureRecognizers>
                        <TapGestureRecognizer
                            CommandParameter="{Binding Path=.}"
                            NumberOfTapsrequired="1"
                            Tapped="OnTapped" />
                    </StackLayout.GestureRecognizers>
                    <Image
                        Aspect="AspectFit"
                        HeightRequest="350"
                        Source="{Binding Path=Image,Converter={StaticResource Key=FillImageFromBytes}}"
                        WidthRequest="325" />
                    <Label HorizontalTextAlignment="Center" Text="{Binding Path=FileName}" />
                </StackLayout>
            </DataTemplate>

....
                            <Label Text="Images" />
                            <syncfusion:SfCarousel x:Name="carousel" ItemTemplate="{StaticResource Key=CarouselitemTemplate}" />

....

我想做的是这个。 TemplateCarouselView.xaml

<?xml version="1.0" encoding="UTF-8" ?>
<syncfusion:SfCarousel
    x:Class="BoomStick.Views.TemplateCarouselView"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:syncfusion="clr-namespace:Syncfusion.SfCarousel.XForms;assembly=Syncfusion.SfCarousel.XForms">
    <syncfusion:SfCarousel.ItemTemplate>
        <DataTemplate>
            <StackLayout Orientation="Vertical">
                <StackLayout.GestureRecognizers>
                    <TapGestureRecognizer
                        CommandParameter="{Binding Path=.}"
                        NumberOfTapsrequired="1"
                        Tapped="{Binding Path=OnTapped}" />
                </StackLayout.GestureRecognizers>
                <Image
                    Aspect="AspectFit"
                    HeightRequest="350"
                    Source="{Binding Path=Image,Converter={StaticResource Key=FillImageFromBytes}}"
                    WidthRequest="325" />
                <Label HorizontalTextAlignment="Center" Text="{Binding Path=FileName}" />
            </StackLayout>
        </DataTemplate>
    </syncfusion:SfCarousel.ItemTemplate>
</syncfusion:SfCarousel

TemplateCarouselView.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Syncfusion.SfCarousel.XForms;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace BoomStick.Views
{
    [XamlCompilation(XamlCompilationoptions.Compile)]
    public partial class TemplateCarouselView : SfCarousel
    {
        public TemplateCarouselView()
        {
            InitializeComponent();
        }

        public static readonly BindableProperty OnTappedProperty = BindableProperty.Create(nameof(OnTapped),typeof(Command),typeof(Command));

        public Command OnTapped
        {
            get
            {
                return (Command)GetValue(OnTappedProperty);
            }

            set
            {
                SetValue(OnTappedProperty,value);
            }
        }
    }
}

我想我可以使用 BindableProperty 来允许调用实例将它自己的指针添加到 Tap Callback 函数。 然后我可以像这样实现这个视图。

<myviews:TemplateCarouselView OnTapped="SomeFunction" />

我的问题是这样的。

  1. 此实现能否继承模板中的 viewmodel?或者我是否需要为每个 BindableProperty 创建 Value="{Binding Path=xxx}" 元素。
  2. OnTapped 的实现没有移交给 TapGestureRecognizer 我不知道如何重载传入的属性以供 xaml 实现接受。
  3. 实现此 View 的每个实例都需要有自己的重载 OnTapped 函数,因此我不能只在 TemplateView 中进行内部调用
  4. 我能否让这个模板使用它自己的内部 viewmodel,同时仍然能够继承父表单 viewmodel

感谢您的任何想法或指点!

干杯! 杰西

解决方法

我终于搞定了! 这是我的工作方式,如果有人有更好的方法或方法来实现这一点,我很乐意听到它!

这是我必须制作的模板类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using BoomStick.Models;
using BoomStick.Services;

using Syncfusion.SfCarousel.XForms;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace BoomStick.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class TemplateCarouselView : SfCarousel
    {
        public DataTemplate dt;

        public TemplateCarouselView()
        {
            InitializeComponent();

            dt = new DataTemplate(() =>
            {
                var keyLayout = new StackLayout();

                var bindPhoto = new Binding()
                {
                    Converter = new FillImageFromBytes(),Path = "Image"
                };

                var bindTapped = new Binding()
                {
                    Path = "OnTapped"
                };

                var bindLocalPath = new Binding()
                {
                    Converter = new FillImageFromBytes(),Path = "."
                };

                var tgRec = new TapGestureRecognizer()
                {
                    CommandParameter = bindLocalPath,NumberOfTapsRequired = 1
                };

                tgRec.Tapped += async (s,e) =>
                {
                    var act = await Application.Current.MainPage.DisplayActionSheet(
                                        StringTools.GetStringResource("szPhotoOptions"),null,StringTools.GetStringResource("szOK"),ActionList.ToArray());
                    await TapHandler.ImageTapHandler((Photos)((TappedEventArgs)e).Parameter,act,KeyButton,ParentObject);
                };

                tgRec.SetBinding(TapGestureRecognizer.CommandProperty,bindTapped);
                tgRec.SetBinding(TapGestureRecognizer.CommandParameterProperty,".");
                keyLayout.GestureRecognizers.Add(tgRec);

                var img = new Image()
                {
                    Aspect = Aspect.AspectFit,HeightRequest = 350,WidthRequest = 250,};
                img.SetBinding(Image.SourceProperty,bindPhoto);
                var lblFileName = new Label()
                {
                    HorizontalTextAlignment = TextAlignment.Center,};
                lblFileName.SetBinding(Label.TextProperty,"FileName");
                keyLayout.Children.Add(img);
                keyLayout.Children.Add(lblFileName);

                return new ViewCell { View = keyLayout };
            });

            Carousel.ItemTemplate = dt;
        }

        public static readonly BindableProperty ActionListProperty = BindableProperty.Create(nameof(ActionList),typeof(List<string>),typeof(List<string>));

        public List<string> ActionList
        {
            get
            {
                return (List<string>)GetValue(ParentObjectProperty);
            }

            set
            {
                SetValue(ParentObjectProperty,value);
            }
        }

        public static readonly BindableProperty ParentObjectProperty = BindableProperty.Create(nameof(ParentObject),typeof(Object),typeof(Object));

        public Object ParentObject
        {
            get
            {
                return (Object)GetValue(ParentObjectProperty);
            }

            set
            {
                SetValue(ParentObjectProperty,value);
            }
        }

        public static readonly BindableProperty KeyButtonProperty = BindableProperty.Create(nameof(KeyButton),typeof(ImageButton),typeof(ImageButton));

        public ImageButton KeyButton
        {
            get
            {
                return (ImageButton)GetValue(KeyButtonProperty);
            }

            set
            {
                SetValue(KeyButtonProperty,value);
            }
        }
    }
}

然后我可以像这样实例化它

<core:TemplateCarouselView
                    x:Name="carousel"
                    ActionList="{Binding Path=ActionList}"
                    KeyButton="{x:Reference KeyImageButton}"
                    ParentObject="{Binding Path=MyClass}" />

这需要一些时间,没有一些帮助我无法完成!

干杯!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。