首页 > 解决方案 > 自定义控件中的选取器

问题描述

我正在构建一些表单(使用TableView)并注意到我对单元格的样式相同。我决定将这个重复的代码重构为一个通用控件。

我正在努力让绑定正确地在选择器上工作。我的自定义控件如下所示:细胞的图片

我的控件是 a ViewCell,因此我可以在 a 中显示它TableView

public partial class PickerCell : ViewCell
{
...
}

我已经能够设置选择器ItemSource,但我无法让SelectedItemorDisplayItemBinding属性工作。

我从 2015 年(现在很古老)看过这篇文章,但我试过了,这些方法被标记为过时,无论如何都不起作用。

我也尝试过控制ctor:

ItemPicker.SetBinding(Picker.ItemsSourceProperty, "ItemSource");
ItemPicker.SetBinding(Picker.SelectedItemProperty, "SelectedItem", BindingMode.TwoWay);

但这也没有用。

我基本上只是想添加一种方法,以便我可以将选择器从我的 xaml 绑定到控件。我真的希望这是可能的,因为我在我的应用程序周围使用了这个精确的视图单元可能 9/10 次。我真的不想重复自己,我通常会在这种情况下创建控件。例如,我有一个类似样式的条目单元格,并且效果很好....

这是我用来设置项目来源的代码:

public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(
    nameof(ItemsSource),
    typeof(IList),
    typeof(PickerCell)
    propertyChanged: (bindable, oldVal, newVal) => ((PickerCell) bindable).OnItemsSourceChanged((IList) newVal)
);

public IList ItemsSource
{
    get { return (IList)GetValue(ItemsSourceProperty); }
    set { SetValue(ItemsSourceProperty, value); }
}

private void OnItemsSourceChanged(IList list)
{
    ItemPicker.ItemsSource = list;
}

我试图从 Xamarin实现一些选择器的代码,但无济于事。

有任何想法吗?

标签: c#xamarinxamarin.formspicker

解决方案


我的自定义选择器也有类似的情况,我想在所选项目更改时实现事件处理程序。下面是我是如何做到的。

在您的自定义选择器的代码隐藏中,实现一个EventHandler属性和私有变量:

private EventHandler onIndexChanged = null;
...
public event EventHandler OnIndexChangedEvent
{
    add
    {
        onIndexChanged = null;
        onIndexChanged = value;
    }
    remove
    {
        onIndexChanged = null;
    }
}

在自定义选择器的 XAML 中,将处理程序添加到SelectedIndexChanged属性:

<Picker
    x:Name="MyPicker"
    SelectedIndexChanged="Handle_SelectedIndexChanged"/>

然后回到你的代码隐藏中,实现这个处理程序:

void Handle_SelectedIndexChanged(object sender, System.EventArgs e)
{
    // Trigger the implemented event, if not null.
    onIndexChanged?.Invoke(sender, e);
}

以上是不可绑定的,所以要实现它,你必须:

  1. 在主视图中设置处理程序:
<?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="MyApp.MyPage"
    xmlns:controls="clr-namespace:MyApp.Controls">
    <ContentPage.Content>
        <StackLayout
            HorizontalOptions="FillAndExpand"
            VerticalOptions="FillAndExpand">
             <controls:CustomPicker
                ItemSource="{Binding SelectionList}"
                OnIndexChangedEvent="Handle_PickerIndexChangedEvent"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
  1. 在视图的代码隐藏中实现处理程序以调用视图模型的处理程序:
private void Handle_PickerIndexChangedEvent(object sender, System.EventArgs e)
{
    viewModel.HandlerIndexChanged(); // or whatever
}

可能有更好的方法来做到这一点,即实施CommandCommandParameter. 但是,即使我不得不稍微改变一下 MVVM 规则,上面的方法对我有用。


推荐阅读