Xamarin 自定义控制命令不起作用

Xamarin Custom Control Command doesn't work

我希望我的自定义控件在单击按钮时触发命令。

    public partial class TestControl : ContentView
    {
        public TestControl()
        {
            InitializeComponent();
            Test = new Command(async () =>
            {
                await Application.Current.MainPage.DisplayAlert("asd", "asd", "asd");
            });
        }

        public ICommand Test { get; }
    }
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:controls="clr-namespace:eTApp.Controls"
    x:DataType="controls:TestControl"
    x:Class="eTApp.Controls.TestControl">
  <ContentView.Content>
      <StackLayout>
            <Button
                Text="press"
                Command="{Binding Test}" />
        </StackLayout>
  </ContentView.Content>
</ContentView>

但是按下按钮没有任何反应。我尝试添加

    <ContentView.BindingContext>
        <controls:TestControl />
    </ContentView.BindingContext>

但是应用程序会在启动时崩溃。我认为那是因为它创建了新的实例并耗尽了内存。

我做错了什么?

编辑: 单击按钮时没有日志错误。在代码隐藏中添加 BindingContext = this; 不会改变任何东西。但是当我在 XAML 文件中添加 BindingContext 时,此日志会在启动时出现并且应用程序冻结:

[Mono] Warning: Degraded allocation.  Consider increasing nursery-size if the warning persists.
[Mono] GC_TAR_BRIDGE bridges 0 objects 0 opaque 0 colors 0 colors-bridged 0 colors-visible 52 xref 3 cache-hit 0 cache-semihit 0 cache-miss 0 setup 0.03ms tarjan 0.03ms scc-setup 0.02ms gather-xref 0.01ms xref-setup 0.01ms cleanup 0.01ms
[Mono] GC_BRIDGE: Complete, was running for 0.14ms
[Mono] GC_MINOR: (Concurrent start) time 22.50ms, stw 56.42ms promoted 900K major size: 16448K in use: 15445K los size: 1024K in use: 871K
[Mono] GC_MAJOR_CONCURRENT_START: (Degraded mode overflow)
[mpanyname.eTAp] Explicit concurrent copying GC freed 406(29KB) AllocSpace objects, 0(0B) LOS objects, 50% free, 1601KB/3MB, paused 499us total 7.510ms
[Mono] GC_TAR_BRIDGE bridges 42 objects 43 opaque 1 colors 42 colors-bridged 42 colors-visible 42 xref 3 cache-hit 0 cache-semihit 0 cache-miss 0 setup 0.04ms tarjan 0.02ms scc-setup 0.03ms gather-xref 0.07ms xref-setup 0.01ms cleanup 0.02ms
[Mono] GC_BRIDGE: Complete, was running for 8.62ms
[Mono] GC_MAJOR_CONCURRENT_FINISH: (finishing) time 734.57ms, stw 22.44ms los size: 1024K in use: 231K
[Mono] GC_MAJOR_SWEEP: major size: 16960K in use: 15533K
[Mono] GC_TAR_BRIDGE bridges 0 objects 0 opaque 0 colors 0 colors-bridged 0 colors-visible 42 xref 3 cache-hit 0 cache-semihit 0 cache-miss 0 setup 0.04ms tarjan 0.02ms scc-setup 0.03ms gather-xref 0.07ms xref-setup 0.01ms cleanup 0.02ms
[Mono] GC_BRIDGE: Complete, was running for 0.24ms
[Mono] GC_MINOR: (Concurrent start) time 19.60ms, stw 38.71ms promoted 300K major size: 32640K in use: 31136K los size: 1024K in use: 504K
[Mono] GC_MAJOR_CONCURRENT_START: (Degraded mode overflow)
[mpanyname.eTAp] Explicit concurrent copying GC freed 3(16KB) AllocSpace objects, 0(0B) LOS objects, 50% free, 1601KB/3MB, paused 402us total 7.396ms
[Mono] GC_TAR_BRIDGE bridges 40 objects 41 opaque 1 colors 40 colors-bridged 40 colors-visible 40 xref 3 cache-hit 0 cache-semihit 0 cache-miss 0 setup 0.05ms tarjan 0.02ms scc-setup 0.01ms gather-xref 0.01ms xref-setup 0.01ms cleanup 0.19ms
[Mono] GC_BRIDGE: Complete, was running for 9.27ms
[Mono] GC_MAJOR_CONCURRENT_FINISH: (finishing) time 520.80ms, stw 26.07ms los size: 1024K in use: 373K
[Mono] GC_MAJOR_SWEEP: major size: 32640K in use: 30767K
[Mono] Warning: Degraded allocation.  Consider increasing nursery-size if the warning persists.
[Mono] GC_TAR_BRIDGE bridges 0 objects 0 opaque 0 colors 0 colors-bridged 0 colors-visible 40 xref 3 cache-hit 0 cache-semihit 0 cache-miss 0 setup 0.05ms tarjan 0.02ms scc-setup 0.01ms gather-xref 0.01ms xref-setup 0.01ms cleanup 0.01ms
[Mono] GC_BRIDGE: Complete, was running for 0.16ms
[Mono] GC_MINOR: (Concurrent start) time 17.46ms, stw 43.08ms promoted 100K major size: 48336K in use: 46517K los size: 2048K in use: 941K
[Mono] GC_MAJOR_CONCURRENT_START: (Degraded mode overflow)
[mpanyname.eTAp] Explicit concurrent copying GC freed 3(16KB) AllocSpace objects, 0(0B) LOS objects, 50% free, 1601KB/3MB, paused 398us total 7.155ms
[Mono] GC_TAR_BRIDGE bridges 40 objects 41 opaque 1 colors 40 colors-bridged 40 colors-visible 40 xref 3 cache-hit 0 cache-semihit 0 cache-miss 0 setup 0.05ms tarjan 0.02ms scc-setup 0.02ms gather-xref 0.01ms xref-setup 0.01ms cleanup 0.11ms
[Mono] GC_BRIDGE: Complete, was running for 8.62ms
[Mono] GC_MAJOR_CONCURRENT_FINISH: (finishing) time 291.47ms, stw 30.74ms los size: 2048K in use: 667K
[Mono] GC_MAJOR_SWEEP: major size: 48208K in use: 46018K
[Mono] GC_TAR_BRIDGE bridges 0 objects 0 opaque 0 colors 0 colors-bridged 0 colors-visible 40 xref 3 cache-hit 0 cache-semihit 0 cache-miss 0 setup 0.05ms tarjan 0.02ms scc-setup 0.02ms gather-xref 0.01ms xref-setup 0.01ms cleanup 0.01ms
[Mono] GC_BRIDGE: Complete, was running for 0.12ms
[Mono] GC_MINOR: (Concurrent start) time 19.62ms, stw 47.45ms promoted 34K major size: 64576K in use: 62420K los size: 2048K in use: 667K
[Mono] GC_MAJOR_CONCURRENT_START: (Degraded mode overflow)
[mpanyname.eTAp] Explicit concurrent copying GC freed 3(16KB) AllocSpace objects, 0(0B) LOS objects, 50% free, 1601KB/3MB, paused 403us total 5.366ms
[Mono] GC_TAR_BRIDGE bridges 40 objects 41 opaque 1 colors 40 colors-bridged 40 colors-visible 40 xref 3 cache-hit 0 cache-semihit 0 cache-miss 0 setup 0.20ms tarjan 0.02ms scc-setup 0.01ms gather-xref 0.01ms xref-setup 0.01ms cleanup 0.12ms
[Mono] GC_BRIDGE: Complete, was running for 7.67ms
[Mono] GC_MAJOR_CONCURRENT_FINISH: (finishing) time 198.38ms, stw 31.63ms los size: 2048K in use: 667K
[Mono] GC_MAJOR_SWEEP: major size: 64400K in use: 61857K
[libc] Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xff4f2fbc in tid 21571 (mpanyname.eTApp), pid 21571 (mpanyname.eTApp)

根据你的描述和代码,你想在自定义控件中创建Icommand,

我做了一个例子,你可以看看,首先创建Icommand BindableProperty。

测试控制:

<ContentView.Content>
    <StackLayout>
        <Button x:Name="btn1" Text="press" />
    </StackLayout>
</ContentView.Content>

  public partial class TestControl : ContentView
{
    public ICommand CommandInButton
    {
        get { return (ICommand)GetValue(CommandInButtonProperty); }
        set { SetValue(CommandInButtonProperty, value); }
    }
   
    public static readonly BindableProperty CommandInButtonProperty = BindableProperty.Create(
    propertyName: "CommandInButton",
    returnType: typeof(ICommand),
    declaringType: typeof(TestControl),
    defaultValue: null,
    propertyChanged: CommandInButtonPropertyChanged);

    private static void CommandInButtonPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var control = (TestControl)bindable;
        control.btn1.Command= (ICommand)newValue;
    }

    public TestControl()
    {
        InitializeComponent();
    }
    
}

您的内容页数:

 <local:TestControl CommandInButton="{Binding Test}" />

 public ICommand Test { get; }
    public Page3()
    {
        InitializeComponent();

        Test = new Command(async () =>
        {
            await Application.Current.MainPage.DisplayAlert("asd", "asd", "asd");
        });

        this.BindingContext = this;
       
    }