我想在Xamarin表单中实现类似下面的内容。
我没有看到使用Objective C的这种实现,所以找不到通过Native渲染它的方法。
如何使用Xamarin表单实现此功能?
部分解决方案:下面的内容将从Xamarin.Forms中呈现您的双列UIPickerView ...当我找到一个基于第一列选择更新第二列的干净方法时,我会更新这个答案
我使用了评论中分享的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,如果你愿意的话
我没有完全探索这条路线,但你也可以通过原生视图(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
以指示您将显示的列数。
祝好运!