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

Comments

Projects
None yet
4 participants
@Yakyyaky

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

This comment has been minimized.

Show comment
Hide comment
@nigel-sampson

nigel-sampson May 3, 2016

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.

Contributor

nigel-sampson commented May 3, 2016

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

This comment has been minimized.

Show comment
Hide comment
@Yakyyaky

Yakyyaky May 3, 2016

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

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

This comment has been minimized.

Show comment
Hide comment
@StephenWard

StephenWard Jun 28, 2016

this fix would be more broadly applicable

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

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

This comment has been minimized.

Show comment
Hide comment
@nigel-sampson

nigel-sampson Nov 14, 2016

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.

Contributor

nigel-sampson commented Nov 14, 2016

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

This comment has been minimized.

Show comment
Hide comment
@nigel-sampson

nigel-sampson May 16, 2017

Contributor

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

Contributor

nigel-sampson commented May 16, 2017

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

@gregbty

This comment has been minimized.

Show comment
Hide comment
@gregbty

gregbty 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)]">

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

This comment has been minimized.

Show comment
Hide comment
@nigel-sampson

nigel-sampson Jun 6, 2017

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.

Contributor

nigel-sampson commented Jun 6, 2017

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

This comment has been minimized.

Show comment
Hide comment
@gregbty

gregbty Jun 6, 2017

Thanks! I missed the added special value configuration.

gregbty commented Jun 6, 2017

Thanks! I missed the added special value configuration.

@gregbty

This comment has been minimized.

Show comment
Hide comment
@gregbty

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

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

This comment has been minimized.

Show comment
Hide comment
@nigel-sampson

nigel-sampson Jun 6, 2017

Contributor

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.

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