c# - 自定义控件中的选择器

标签 c# xamarin xamarin.forms picker

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

我正在努力让绑定(bind)在选择器上正确工作。我的自定义控件如下所示:picture of the cell

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

public partial class PickerCell : ViewCell
{
...
}

我已经能够设置选取器 ItemSource,但是我无法使 SelectedItemDisplayItemBinding 属性起作用。

我看过 this post from 2015 (现在很古老)但我尝试过,但这些方法被标记为过时并且无论如何都不起作用。

我也在控件构造器中尝试过:

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

但这也不起作用。

我基本上只是想添加一种方法,以便我可以将选择器从我的 xaml 绑定(bind)到控件。我真的希望这是可能的,因为我在我的应用程序周围使用这个精确的 View 单元格可能有 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;
}

我尝试为选择器实现一些代码 from Xamarin但无济于事。

有什么想法吗?

最佳答案

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

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

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);
}

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

  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. 在 View 的代码隐藏中实现处理程序以调用 View 模型的处理程序:
private void Handle_PickerIndexChangedEvent(object sender, System.EventArgs e)
{
    viewModel.HandlerIndexChanged(); // or whatever
}

可能有更好的方法来做到这一点,即实现 CommandCommandParameter。但是,即使我不得不稍微改变 MVVM 规则,以上内容对我也有效。

关于c# - 自定义控件中的选择器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54313376/

相关文章:

c# - 无法连接到 Android 上的 TCP 端口

visual-studio - Visual Studio Xamarin.UITest : "System.Exception : Android SDK not found." running UITests

c# - ViewPager DestroyItem 无法转换对象

c# - 如何在 For 循环中创建标签

c# - ASP.NET Core (HttpSys) 路由在本地工作,但在部署时不工作

c# - 在 Tumblr 上创建博客帖子时 OAuth 失败(不断收到 401/未授权)

android - TextInputLayout 密码圆角切换

xamarin - 如何基于其中包含 StackLayout 的 Frame 创建新的 Xamarin 元素?

xamarin.forms - 来自appcenter的android 11设备上的应用程序未安装错误

c# - 是否有用于 C# 的 DataBinder.Eval 的快速版本?