Open grokys opened 4 years ago
I think we should accept all.
The most confusing for new users (like I am/was) is that events are not visible in Intellisense. I have no idea which events exist without knowing the source code in detail. This should be fixed first in my opinion, otherwise this enhancement will not do much for new user experience.
After this is fixed, I agree with your idea. All should be accepted. I wouldn't want to use CommandParameter however since it would prevent using this by the user. I mean what happens if the user tries something like this: <Button PointerPressed="{Binding MyMethod}" CommandParameter={....}>
? Which gets overridden? Which gets ignored? Does this even produce an error in XAML or on publish?
I have mixed feelings, I've sometimes wanted to sent a click command without using a button. I don't think I would use it as described as I don't generally want to send view specific objects to the viewmodel. I guess you could use converters to convert from PointerPressedEventArgs to something view agnostic but that is getting complex again. I can see in non mvvm cases where the datacontext could be the view that this might be useful and some may be quite happy with view objects in their view models. I wonder if the CommandParameter could be bound to properties of the event.
CommandParameter should always belong to the bound Command. If you bind a Command to an event the event args should be used as parameter. My opinion.
I wouldn't want to use CommandParameter however since it would prevent using this by the user. I mean what happens if the user tries something like this:
CommandParameter
for sending data to event handlers doesn't make much sense: there's only a single CommanParameter
property, and only on certain classes.
How would CommandParameter
work with multiple event handlers?
<Button PointerPressed="{Binding MyMethod}" DragStart="{Binding AnotherMethod}" CommandParameter={....}>
IMO CommandParameter
can only affect the parameters sent to the Command
property as @Gillibald says.
If you wanted CommandParameter to work I guess you would have one for each event PointerPressedParameter
It is totally fine to process event args in the ViewModel. An event isn't tied to the view. You can even raise these events in a unit test.
It makes the ViewModel less platform agnostic, that may not matter a lot of the time.
To be honest I'd rather have some way to embed inline C# code. Event args are way too platform specific to be passed directly to the view model, so there should be some kind of a medium that would convert those to platform-independent call.
To not overcomplicate things we can just ignore the event args. This is all about making things simpler. Inline code is a different feature that can be useful.
To my current understanding, there is currently no way to access events like PointerEnter
without using code-behind or libraries like https://github.com/wieslawsoltes/AvaloniaBehaviors, right? So this would be, from my user perspective, a great addition.
In UWP we have x:Bind feature: Event Binding Event binding is a unique feature for compiled binding. It enables you to specify the handler for an event using a binding, rather than it having to be a method on the code behind. For example: Click="{x:Bind rootFrame.GoForward}".
For events, the target method must not be overloaded and must also:
In my opinion it's useful feature in UWP, but isn't friendly for MVVM. Maybe it should allow to pass custom parameters: Click="{Binding ViewModel.RunCommand(ViewModel.Parameter)}" or Click="{Binding ViewModel.SearchCommand(SomeTextBox.Text)}" or Click="{Binding ViewModel.CalculateMethod(SomeTextBox.Text.Length, 5)}"
However, it should depend on DataContext with classic Binding, as it more expected for non-UWP developers.
DevExpress MVVM has several really nice extensions to enable MVVM shortcuts. Maybe take a look at these for some ideas?
https://docs.devexpress.com/WPF/115770/mvvm-framework/dxbinding
@aetaylor it should be possible to port this markup extension in Avalonia too, if there is any source code. But I guess it heavily relies on reflection.
I think this is a great idea, it needs to be added
Coming from Angular, I really though this would have been already in Avalonia. How would one go about natively implementing a pointerpressed event from XAML on a control without making a custom control? (In MVVM)
Edit: Also if I were to pick one, I'd do:
void MyMethod(object sender, PointerPressedEventArgs e); // Sender and event args
To be honest I'd rather have some way to embed inline C# code. Event args are way too platform specific to be passed directly to the view model, so there should be some kind of a medium that would convert those to platform-independent call.
Not sure I understand, though I'm very new to Avalonia. Wouldn't it be the same as doing:
public void OnPointerPressed(object sender, PointerPressedEventArgs args);
Or am I missing something deeper? Because if the compiler does output that, then it'd be the same as me writing an override anyway.
any progress on this?
also a an alternative i think you could use ReactiveWindow & this.WhenActivated(action => ...) to add/remove event handlers (sure xaml only version would be nice, but this is doable now ...)
Still Avalonia.Behaviors is the way to go if you need that functionality. Esp. custom events can be very powerful.
Still Avalonia.Behaviors is the way to go if you need that functionality. Esp. custom events can be very powerful.
@timunie correct me if I'm wrong but, doesn't Avalonia.Behaviors take a lot of boiler plate for each event? When I looked at it (which wasn't too long) it's definitely not as simple as setting an attribute in xaml.
Yeah, having a way to bind to it would be a great feature, but it's not that high on our list atm. If someone wants to contribute it, I guess it is welcome. But the API should be discussed before one starts.
@timunie Maybe just copy code from https://github.com/Serg046/EventBinder?
.
(can potentially be extended with the full syntax, but fine as is?)$0
, $1
for passing event arguments (doesn't seem to conflict with Avalonia's syntax?)Also code completion would need to include events ideally. Getting JetBrains to update ReSharper (it complains about bindings to events and doesn't include them in completion but does highlight them) is a different story but can probably happen within 2-3 years.
Interesting project and idea. Maybe this should be added to https://github.com/AvaloniaCommunity/awesome-avalonia . If you have some free time, please provide a PR to them.
@Athari no, we can't copy paste anything. Because it should be integrated into XamlX compiler and not be a markup extensions, and EventBinding syntax wasn't even discussed here before. The most promising was mix of @grokys proposal and/or x:Bind.
But either way, EventBinding port to Avalonia is a great addition to the ecosystem!
@maxkatz6 Just to be clear, are the issues with integrating Serg046's EventBinder limited to compatibility with XamlX compiler (does that mean compiled bindings?), or do they apply to the design too? Because design-wise, I think EventBinding is superior to alternatives (no tying of VM to V types + passing parameters properly).
That being said, having a built-in Binding
which supports methods would solve 80% of my problems, and it can later be extended with x:Bind
/DXBinding
-ish syntax.
I would also be interested in having event handlers binding supported in Avalonia. Even if not totally MVVM friendly, it would allow more code to bemoved away from the code behind of the forms, and moved to the view model, where it could be more easily unit tested.
Avalonia, like WPF and UWP has two different ways of handling interactions: events and commands. This can be confusing for new users, and awkward for experienced users because:
What if it were possible to put bindings to commands and methods in event handlers? There are two questions I think:
Some ideas:
Methods
The possible signatures for this method could be:
Would we want to accept all of these or just some?
Commands
The event args could probably be passed as the
CommandParameter
?Thoughts?
Any thoughts on this? Good idea? Bad idea? Would it make things more or less confusing?