Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$selectedItem does not appear to be implemented #319

Closed
Yakyyaky opened this issue May 3, 2016 · 10 comments
Closed

$selectedItem does not appear to be implemented #319

Yakyyaky opened this issue May 3, 2016 · 10 comments
Milestone

Comments

@Yakyyaky
Copy link

Yakyyaky commented May 3, 2016

Hi, I am using CM for Xamarin Forms for android and iOS with Autofac as DI replacement.

I went through http://caliburnmicro.com/announcements/3.0.0 and in there was a snippet of using ListView with selected item.
<ListView ItemsSource="{Binding Features}" HasUnevenRows="True" cm:Message.Attach="[Event ItemSelected] = [ShowFeature($selectedItem)]">

I found that $selectedItem is not working and upon further inspect, I can concluded it's not implemented at all in MessageBinder. For the moment I have added the following to get it working.
MessageBinder.SpecialValues.Add("$selecteditem", context => { var lv = context.Source as ListView; return lv?.SelectedItem; });
Using safe cast instead of reflection because afaik ListView is the only with this property.

Is this feature deprecated/remove/missed/incorrectly documented/implemented/some other? or have I missed something?
Thanks.

@nigel-sampson
Copy link
Contributor

You're right it's not currently implemented in the base library and I lifted it from a sample it's something I think we'll add in a upcoming version.

Thanks for bringing this to my attention.

@nigel-sampson nigel-sampson added this to the v3.1.0 milestone May 3, 2016
@Yakyyaky
Copy link
Author

Yakyyaky commented May 3, 2016

Awesome, I look forward to it.
The sample you linked looks mighty useful for review as well. Thanks for that.

@StephenWard
Copy link

this fix would be more broadly applicable

MessageBinder.SpecialValues.Add("$selectedItem", context => {
if (context.Source == null)
return null;
return ((dynamic)context.Source).SelectedItem;
});

@nigel-sampson
Copy link
Contributor

There's one major problem with implementing $selectedItem in Xamarin.Forms.

TriggerAction<T> doesn't receive the arguments from the appropriate trigger. All the XAML platforms support this and by convention the event trigger passes through the event args.

We can do it with ListView.SelectedItem, however you also need to support deselecting the item which may not be something you want.

@nigel-sampson
Copy link
Contributor

I've implemented $clickedItem in WinRT projects for now. Not comfortable at the moment tackling Xamarin.Forms here.

@gregbty
Copy link

gregbty commented Jun 6, 2017

What's the current workaround for XForms? The syntax is still referenced in the updated samples:

cm:Message.Attach="[Event ItemSelected] = [ShowFeature($selectedItem)]">

@nigel-sampson
Copy link
Contributor

The sample itself creates the implementation in FormsApp which you're free to copy.

I'm not keen on adding it to the framework due to the stateful nature of SelectedItem, what tends to happen if people aren't careful is that they forget to clear it and going back and hitting the same item doesn't change the value and trigger the event.

I'll double check this in later versions of the Forms across multiple platforms and if it's good then I'll add it in.

@gregbty
Copy link

gregbty commented Jun 6, 2017

Thanks! I missed the added special value configuration.

@gregbty
Copy link

gregbty commented Jun 6, 2017

Is there a reason why the event args can not be used? Is this also not supported with Caliburn + XForms? The value of EventArgs in the context seems to always be null.

forms:Message.Attach="[Event ItemSelected] = [NavigateToItemAsync($selectedItem)]"
MessageBinder.SpecialValues.Add("$selecteditem", c =>
{
  var eventArgs = c.EventArgs as SelectedItemChangedEventArgs;
  return eventArgs?.SelectedItem;
});

Is this the issue you referred to above with TriggerAction<T>?

@nigel-sampson
Copy link
Contributor

nigel-sampson commented Jun 6, 2017

Yup, first a bit of internals. They way Caliburn.Micro works is taking the string [Event ItemSelected] = [NavigateToItemAsync($selectedItem)], parsing it and producing something like

<EventTrigger Event="ItemSelected">
    <cm:ActionMessage MethodName="NavigateToItemAsync">
        <cm:Parameter Value="$selectedItem" />
    </cm:ActionMessage>
</EventTrigger>

Where EventTrigger is the implementation that comes with the platform in question. We do this for a number of reasons.

  1. Allows developers to extend the parser to create their own triggers.
  2. Allows developers to fall back to the extended synxtax above if they have complicated requirements not workable in the parser.
  3. Separates the trigger from the action.

One of the differences between Xamarin.Forms and the others (such as UWP) is the interface between the trigger and the action. Specifically on the Microsoft developed platforms there's an optional argument passed to the action (which we enter into EventArgs). The default implementation of EventTrigger on these platforms pass the event args, but other triggers can pass whatever is appropriate.

Xamarin.Forms however doesn't have that parameter. The interface itself doesn't allow this to be passed between the two.

It's unfortunate but it will require a change to Xamarin.Forms to deal with this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants