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

If set x:DataType to a control type, binding command to method in the control is invalid for Android #17829

Open
Supheria opened this issue Dec 25, 2024 · 2 comments
Labels

Comments

@Supheria
Copy link

Supheria commented Dec 25, 2024

Describe the bug

When set DataContext to a control type, binding command to method in the control will cause InvalidCastException for Android, but which works ok on Windows (Linux and iOS hasn't tested).

Versions:

  • Avalonia: 11.2.3
  • Avalonia.Android: 11.2.3
  • .Net: 9
  • Android Platform API level: 35

Content of the exception:

System.InvalidCastException: Specified cast is not valid.
at CompiledAvaloniaXaml.XamlIlTrampolines.Sample:Sample.Views.MyBorder+Test_0!CommandExecuteTrampoline(Object , Object )
at Avalonia.Data.Core.ExpressionNodes.MethodCommandNode.Command.Execute(Object parameter)
at Avalonia.Controls.Button.OnClick()
at Avalonia.Controls.Button.OnPointerReleased(PointerReleasedEventArgs e)
at Avalonia.Input.InputElement.<>c.<.cctor>b__32_9(InputElement x, PointerReleasedEventArgs e)
at Avalonia.Interactivity.RoutedEvent1.<>c__DisplayClass1_01[[Avalonia.Input.PointerReleasedEventArgs, Avalonia.Base, Version=11.2.3.0, Culture=neutral, PublicKeyToken=c8d484a7012f9a8b],[Avalonia.Input.InputElement, Avalonia.Base, Version=11.2.3.0, Culture=neutral, PublicKeyToken=c8d484a7012f9a8b]].g__Adapter|0(Object sender, RoutedEventArgs e)
at Avalonia.Interactivity.RoutedEvent.<>c__DisplayClass23_0.b__0(ValueTuple2 args) at Avalonia.Reactive.AnonymousObserver1[[System.ValueTuple2[[System.Object, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Avalonia.Interactivity.RoutedEventArgs, Avalonia.Base, Version=11.2.3.0, Culture=neutral, PublicKeyToken=c8d484a7012f9a8b]], System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnNext(ValueTuple2 value)
at Avalonia.Reactive.LightweightObservableBase1[[System.ValueTuple2[[System.Object, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Avalonia.Interactivity.RoutedEventArgs, Avalonia.Base, Version=11.2.3.0, Culture=neutral, PublicKeyToken=c8d484a7012f9a8b]], System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].PublishNext(ValueTuple2 value) at Avalonia.Reactive.LightweightSubject1[[System.ValueTuple2[[System.Object, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Avalonia.Interactivity.RoutedEventArgs, Avalonia.Base, Version=11.2.3.0, Culture=neutral, PublicKeyToken=c8d484a7012f9a8b]], System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnNext(ValueTuple2 value)
at Avalonia.Interactivity.RoutedEvent.InvokeRaised(Object sender, RoutedEventArgs e)
at Avalonia.Interactivity.EventRoute.RaiseEventImpl(RoutedEventArgs e)
at Avalonia.Interactivity.EventRoute.RaiseEvent(Interactive source, RoutedEventArgs e)
at Avalonia.Interactivity.Interactive.RaiseEvent(RoutedEventArgs e)
at Avalonia.Input.TouchDevice.ProcessRawEvent(RawInputEventArgs ev)
at Avalonia.Input.InputManager.ProcessInput(RawInputEventArgs e)
at Avalonia.Controls.TopLevel.<>c.b__145_0(Object state)
at Avalonia.Threading.Dispatcher.Send(SendOrPostCallback action, Object arg, Nullable`1 priority)
at Avalonia.Controls.TopLevel.HandleInput(RawInputEventArgs e)
at Avalonia.Android.Platform.Specific.Helpers.AndroidMotionEventsHelper.DispatchMotionEvent(MotionEvent e, Boolean& callBase)
at Avalonia.Android.Platform.SkiaPlatform.TopLevelImpl.ViewImpl.DispatchTouchEvent(MotionEvent e)
at Android.Views.View.n_DispatchTouchEvent_Landroid_view_MotionEvent_(IntPtr jnienv, IntPtr native__this, IntPtr native_e) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net9.0/android-35/mcw/Android.Views.View.cs:line 16430
at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPL_Z(_JniMarshal_PPL_Z callback, IntPtr jnienv, IntPtr klazz, IntPtr p0) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:line 132

To Reproduce

Create a solution with template: Avalonia Cross Platform Application

MainView.cs

using Avalonia.Controls;

namespace Sample.Views;

public partial class MainView : UserControl
{
    public MainView()
    {
        InitializeComponent();
        DataContext = TestBorder;
    }
}

MainView.axml

<UserControl
    x:Class="Sample.Views.MainView"
    x:DataType="vm:MainViewModel"
    xmlns="https://github.com/avaloniaui"
    xmlns:views="using:Sample.Views"
    xmlns:vm="clr-namespace:Sample.ViewModels"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <views:MyBorder Name="TestBorder">
        <Button
            Command="{Binding Test}"
            Content="Test"
            x:DataType="views:MyBorder" />
    </views:MyBorder>
</UserControl>

MyBorder.cs

using System.Diagnostics;
using Avalonia.Controls;

namespace Sample.Views;

public class MyBorder : Border
{
    public void Test()
    {
        Debug.WriteLine("test invoked");
    }
}

Expected behavior

Debug outputs "test invoked" same as on Windows.

Avalonia version

11.2.3

OS

Android

Additional context

No response

@Supheria Supheria added the bug label Dec 25, 2024
@Supheria Supheria changed the title If set x:DataType to a control type, binding command to method in the control is not invalid for Android If set x:DataType to a control type, binding command to method in the control is invalid for Android Dec 25, 2024
@oli-g-sk
Copy link

I was just about to report this.

In my case, it definitely happens on Windows.

public class MainViewModel : ViewModelBase
{
    public ChildViewModel Child { get; } = new();
}

public class ChildViewModel : ViewModelBase
{
    public string HelloWorld { get; } = "Hello World";
}
<Window xmlns="https://github.com/avaloniaui"
        xmlns:app="clr-namespace:AvaloniaApplication2"
        x:Class="AvaloniaApplication2.MainWindow"
        x:DataType="app:MainViewModel">
    <Window.DataContext>
        <app:MainViewModel />
    </Window.DataContext>
    
    <app:ChildView DataContext="{Binding Child}" />
</Window>
<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:app="clr-namespace:AvaloniaApplication2"
             x:Class="AvaloniaApplication2.ChildView"
             x:DataType="app:ChildViewModel">
    <TextBox Text="{Binding HelloWorld}" />
</UserControl>

@timunie
Copy link
Contributor

timunie commented Dec 26, 2024

@oli-g-sk your issue seems to be completely unrelated and I doubt it is even a bug in Avalonia. Please open a discussion and share the entire AvaloniaApplication2 test project without bin and obj folders there.

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

No branches or pull requests

3 participants