Stylet icon indicating copy to clipboard operation
Stylet copied to clipboard

ActionExtension for events does not respect guard proeprty

Open Tyrrrz opened this issue 6 years ago • 5 comments
trafficstars

From wiki:

The syntax is exactly the same, although there's no concept of a guard property here.

Why? I want to be able to set MouseLeftButtonUp="{s:Action SomeAction}" and only have the handler actually execute when the guard property lets it. The justification is that I want to be able to use events in the same way I use commands, without having to use some kind of EventToCommand contraption.

Tyrrrz avatar Dec 01 '18 12:12 Tyrrrz

Because events have no concept of "can execute". ICommand has the CanExecute method, but events have nothing of the sort. There's no way to disable a button using only it's MouseLeftButtonUp event.

If you want to prevent your event handler from running in particular cases, put the code if (!CanSomeAction) return at the top.

canton7 avatar Dec 01 '18 12:12 canton7

That's true that the control cannot (and should not) be disabled. That said, from view-model level of abstraction, since Stylet effectively removes the concept of ICommand (which is amazing), the CanXYZ guard properties should no longer be tied to ICommand.CanExecute. As a person using Stylet, I greatly enjoy the fact that I don't have to bother with ICommand or its implementation and as such I prefer not to think about it. To me, CanXYZ is a property that simply answers "can XYZ be executed?" without having anything to do with controls being disabled or not. I would say controls being disabled is more like an appreciated side effect.

PS: I'm already doing (!CanSomeAction) return but I was trying to understand the design decision.

Tyrrrz avatar Dec 01 '18 13:12 Tyrrrz

Also, to further iterate my point, System.Windows.Interactivity lets us do this:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="SomeEvent">
       <i:InvokeCommandAction Command="{Binding Path=SomeCommand, Mode=OneWay}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

It will respect the ICommand.CanExecute and ignore the event if it's false. It will obviously not disable the control or anything of the sort.

Tyrrrz avatar Dec 01 '18 13:12 Tyrrrz

I disagree - Stylet tries to avoid introducing too much magic. Someone reading a project written with Stylet shouldn't have to do too much guessing/reading to figure out what's going on. Guard properties are already about as much magic as I'm comfortable with (they only exist because they're so convenient). Developers already have to care about the difference between events and ICommands, as the latter can disable controls and the former can't. Letting guards have different behaviour based on whether they're applied to an event or ICommand just makes things more confusing.

canton7 avatar Dec 01 '18 13:12 canton7

You could also argue that because "Guard properties are already enough magic" I initially didn't expect and found it unintuitive that guard properties were completely ignored with events. Also coming from the "non-magic" background, I expected it to work the way it does with Interaction.Triggers, as shown above.

Tyrrrz avatar Dec 01 '18 13:12 Tyrrrz