如何在Xamarin中实现Treelist下拉列表?

问题描述 投票:1回答:1

我想在Xamarin表单中实现类似下面的内容。

我没有看到使用Objective C的这种实现,所以找不到通过Native渲染它的方法。

如何使用Xamarin表单实现此功能?

https://demo.mobiscroll.com/javascript/list/display#

enter image description here

objective-c xamarin.forms
1个回答
1
投票

部分解决方案:下面的内容将从Xamarin.Forms中呈现您的双列UIPickerView ...当我找到一个基于第一列选择更新第二列的干净方法时,我会更新这个答案

Option 1: Custom Renderer

我使用了评论中分享的documentation @Junior Jiang来激发一个适合您需求的快速自定义渲染器。

首先,在shared / Xamarin.Forms项目中进行占位符控件:

namespace samples.core.Controls
{
    public class MultiPickerControl : Xamarin.Forms.StackLayout
    {
        public MultiPickerControl()
        {
            // Just a placeholder
        }
    }
}

然后,在iOS项目中创建渲染器:

[assembly: ExportRenderer(typeof(samples.core.Controls.MultiPickerControl), typeof(samples.iOS.Controls.Picker.MultiPickerRenderer))]
namespace samples.iOS.Controls.Picker
{
    public class MultiPickerRenderer : ViewRenderer
    {
        static UIPickerView pickerControl;
        static PeopleModel pickerModel = new PeopleModel(new UILabel());

        public MultiPickerRenderer()
        {
            pickerControl = new UIPickerView(
                new CGRect(
                    UIScreen.MainScreen.Bounds.X - UIScreen.MainScreen.Bounds.Width,
                    UIScreen.MainScreen.Bounds.Height - 230,
                    UIScreen.MainScreen.Bounds.Width,
                    180))
            {
                Model = pickerModel
            };
        }

        protected override void OnElementChanged(ElementChangedEventArgs<View> e)
        {
            base.OnElementChanged(e);

            if(Control != null)
            {
                Control.Add(pickerControl);
            }

            if(e.NewElement != null)
            {
                (e.NewElement as StackLayout).Children.Add(pickerControl);
            }
        }
    }
}

你还需要一个UIPickerViewModel给你的选择器。此示例直接从上面的文档中获取,可以逐字复制到您的iOS项目中

    public class PeopleModel : UIPickerViewModel
    {
        public string[] names = new string[] {
            "Amy Burns",
            "Kevin Mullins",
            "Craig Dunn",
            "Joel Martinez",
            "Charles Petzold",
            "David Britch",
            "Mark McLemore",
            "Tom Opegenorth",
            "Joseph Hill",
            "Miguel De Icaza"
        };

        private UILabel personLabel;

        public PeopleModel(UILabel personLabel)
        {
            this.personLabel = personLabel;
        }

        public override nint GetComponentCount(UIPickerView pickerView)
        {
            return 2; // This determines how many columns are rendered
        }

        public override nint GetRowsInComponent(UIPickerView pickerView, nint component)
        {
            return names.Length;
        }

        public override string GetTitle(UIPickerView pickerView, nint row, nint component)
        {
            if (component == 0)
                return names[row];
            else
                return row.ToString();
        }

        public override void Selected(UIPickerView pickerView, nint row, nint component)
        {
            // You can update the possible values for column 2 here (I think)
            personLabel.Text = $"This person is: {names[pickerView.SelectedRowInComponent(0)]},\n they are number {pickerView.SelectedRowInComponent(1)}";
        }

        public override nfloat GetComponentWidth(UIPickerView picker, nint component)
        {
            if (component == 0)
                return 240f;
            else
                return 40f;
        }

        public override nfloat GetRowHeight(UIPickerView picker, nint component)
        {
            return 40f;
        }
    }

最后,在标记(或后面的代码)中引用占位符控件。 Xamarin将在您的代码运行时解决平台实现。

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:controls="clr-namespace:samples.core.Controls;assembly=samples.core"
             x:Class="samples.core.Views.EntryMoveNextView" 
             xmlns:ctrl="clr-namespace:samples.core.Controls;assembly=samples.core">
    <ContentPage.Content>
        <StackLayout Padding="15,25">
            <controls:MultiPickerControl x:Name="MultiPicker"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

结果应如下所示:

一定要加入可用的事件我已经将上面的例子添加到samples repo on my GitHub,如果你愿意的话

Option 2: Native View

我没有完全探索这条路线,但你也可以通过原生视图(documentation)来实现这一目标。要点看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:ios="clr-namespace:UIKit;assembly=Xamarin.iOS;targetPlatform=iOS"
             x:Class="samples.core.Views.EntryMoveNextView" 
             xmlns:ctrl="clr-namespace:samples.core.Controls;assembly=samples.core">
    <ContentPage.Content>
        <StackLayout Padding="15,25">
            <ios:UIPickerView>
                <!-- Manipulate UIPickerView Properties Here -->
            </ios:UIPickerView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

与上面的链接文档一样,请务必在GetComponentCount中设置UIPickerViewModel以指示您将显示的列数。

祝好运!

© www.soinside.com 2019 - 2024. All rights reserved.