【问题标题】:Xamarin Forms Bind-able Picker - How to get selected item in ViewModelXamarin Forms Bind-able Picker - 如何在 ViewModel 中获取所选项目
【发布时间】:2017-11-01 03:03:18
【问题描述】:

我正在使用 Xamarin 表单:2.3.4.247 棱镜库:6.3.0

以下是最新 Xamarin Forms 中具有 Bind-able Picker ass 的代码: 查看

将我认为的(棱镜)行为注册为以下

xmlns:b="clr-namespace:Prism.Behaviors;assembly=Prism.Forms"

Picker 还显示 CountryCodes 的数据,这是 PickerItem

类型的列表
       <Picker  ItemsSource="{Binding CountryCodes}" Title="Select Country"  ItemDisplayBinding="{Binding Name}">
            <Picker.Behaviors>
                <b:EventToCommandBehavior EventName="SelectedIndexChanged" Command="{Binding ItemTappedCommand}" EventArgsParameterPath="Item" />
            </Picker.Behaviors>
        </Picker>

在各自的视图模型中,我将命令定义为如下

public DelegateCommand<PickerItem> ItemTappedCommand { get; }

在构造函数中:

ItemTappedCommand = new DelegateCommand<PickerItem>(OnCountryPickerTapCommandExecuted);

委托功能如下:

private void OnCountryPickerTapCommandExecuted(PickerItem item)
{
    SelectedCountryCode = item.Code;//some property I want it to assign
}

问题是选择器绑定正确,但是在选择/更改选择时没有任何反应:

我在棱镜中遗漏了什么吗?

【问题讨论】:

  • 您是否尝试过双向绑定?
  • @Diceble - 是的也试过了,没有任何变化,几次我得到一个未处理的异常发生。但是我无法调试它发生在哪条线上。与“EventArgsParameterPath”有关,这就是我能想到的。
  • 如果我从代码中删除 EventArgsParameterPath="Item" 参数,我可以进行调试,并执行 OnCountryPickerTapCommandExecuted(PickerItem Item),但很明显该项目返回 null。所以这似乎是参数路径有一些我无法解决的问题,请大家帮忙。
  • 不确定为什么我的 LogCat 显示 NullReferenceException:如所见 ---------------->Info 2411 MonoDroid System.NullReferenceException:对象引用未设置为实例的一个对象。在 Prism.Behaviors.EventToCommandBehavior.OnEventRaised (System.Object sender, System.EventArgs eventArgs) [0x00054] in :0 .... b__0 (System.Object s, Android.Content.DialogClickEventArgs e) [ 0x00000] 在 C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\AppCompat\PickerRenderer.cs:103

标签: xamarin xamarin.forms prism


【解决方案1】:

您不需要事件来命令行为。你可以看到这个answer 了解如何使用选择器。该示例未使用 Prism,但其工作方式完全相同。

<?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:local="clr-namespace:PickerDemo" 
             x:Class="PickerDemo.PickerDemoPage">
    <ContentPage.BindingContext>
        <local:PickerDemoPageViewModel />
    </ContentPage.BindingContext>
    <StackLayout Padding="10,20">
        <!-- Picker with explicitly set values in XAML -->
        <Picker SelectedItem="{Binding SelectedItem}">
            <Picker.Items>
                <x:String>Item 1</x:String>
                <x:String>Item 2</x:String>
            </Picker.Items>
        </Picker>
        <Label Text="{Binding SelectedItem,StringFormat='You Selected: {0}'}" />

        <!-- Picker with Dynamically set values -->
        <Picker ItemsSource="{Binding SomeCollection}" SelectedItem="{Binding AnotherItem}" />
        <Label Text="{Binding AnotherItem,StringFormat='You picked: {0}'}" />

        <!-- Date Picker using a custom display format -->
        <DatePicker Date="{Binding SomeDate}" Format="MMMM dd, yyyy" />
        <Label Text="{Binding SomeDate,StringFormat='{0:dd MMMM, yyyy}'}" />
    </StackLayout>

</ContentPage>

编辑:

没有 SeletedItemChanged 事件,只有 SelectedItemIndexChanged 事件,这有点毫无意义。但是,在 Prism 6.3 中,您可以执行以下操作:

public class FooBar : BindableBase
{
    private INavigationService _navigationService { get; }

    public FooBar(INavigationService navigationService)
    {
        _navigationService = navigationService;
    }

    private string _foo;
    public string Foo
    {
        get { return _foo; }
        set { SetProperty(ref _foo, value, OnFooChanged);}
    }

    private async void OnFooChanged() => 
        await _navigationService.NavigateAsync("SomePage", new NavigationParameters() { { "foo", Foo } });
}

【讨论】:

  • 实际上我需要在下一个视图中选择项,Prism 允许传递导航参数(以及选择项),上面的示例仅显示相同的视图绑定,这很简单,您能进一步建议吗?跨度>
  • 顺便说一句,Fody weaver 需要什么?只是像在 Prism 中那样绑定 PropertyChanged? Fody 是否提供相同的功能。
  • 我相信上面的更新应该在那里回答你的问题。该示例使用 Fody PropertyChanged 来减少代码。您可以将它与 BindableBase 或任何基本 ViewModel 类一起使用。您可以在我的blog post 上阅读更多相关信息。请注意,最新版本的 Fody PropertyChanged 实际上不再需要使用 InjectPropertyChanged 属性,因为如果您添加了 INotifyPropertyChanged,它将自动获取它
  • Brian Lagunas,在此处的 XF 论坛中指出 (forums.xamarin.com/discussion/comment/277628#Comment_277628) 以及上述答案也符合标准...我还发现我的代码具有不正确的 Type 属性 而不是 Type ,这也影响了功能。所以我仍然会感谢大家并将其标记为答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多