1
votes

I am using Xamarin forms : 2.3.4.247 Prism Library : 6.3.0

The following is the code having Bind-able Picker ass in latest Xamarin Forms: VIEW

Registered the (prism) behaviors in my view as under

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

Picker also showing the data of CountryCodes which is a list of type 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>

in respective view model I've defined the command as under

public DelegateCommand<PickerItem> ItemTappedCommand { get; }

and In constructor:

ItemTappedCommand = new DelegateCommand<PickerItem>(OnCountryPickerTapCommandExecuted);

The delegated function is as under:

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

The issue is the picker is binding properly, however when selecting/changing selection nothing happen:

Am I missing something, in prism?

1
have you tried to make your binding twoway?Diceble
@Diceble - Yup tried that as well, nothing changes, few times I get An unhandled exception occurred. However I can not debug it on which lines this is happening. Something is to do with 'EventArgsParameterPath' thats what I could figure out.NBaua
If I remove the EventArgsParameterPath="Item" parameter from code, I can dubug, and OnCountryPickerTapCommandExecuted(PickerItem Item) is executed, however as obvious the item is returned null. so this seems that Parameter path has some issues which I can not resolve, help please guys.NBaua
not sure why however my LogCat shows NullReferenceException: as seen ---------------->Info 2411 MonoDroid System.NullReferenceException: Object reference not set to an instance of an object. at Prism.Behaviors.EventToCommandBehavior.OnEventRaised (System.Object sender, System.EventArgs eventArgs) [0x00054] in <7a32c28f35024e719a93e31b4d1e3d2a>:0 .... <OnClick>b__0 (System.Object s, Android.Content.DialogClickEventArgs e) [0x00000] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\AppCompat\PickerRenderer.cs:103NBaua

1 Answers

1
votes

You shouldn't need an event to command behavior. You can see this answer on how to work with pickers. The example isn't using Prism but how it works is the exact same.

<?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>

EDIT:

There is no SeletedItemChanged event, only a SelectedItemIndexChanged event, which is kind of pointless. In Prism 6.3 you can however do something like the following:

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