Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mvvm Xamarin表单和TabgestureRecognitor不使用命令激发_Mvvm_Xamarin_Xamarin.forms - Fatal编程技术网

Mvvm Xamarin表单和TabgestureRecognitor不使用命令激发

Mvvm Xamarin表单和TabgestureRecognitor不使用命令激发,mvvm,xamarin,xamarin.forms,Mvvm,Xamarin,Xamarin.forms,我对Xamarin表单(在Android和iOS上测试)有这个问题 我有一个简单的页面 using System; using Xamarin.Forms; namespace BugTGR { public class PageMain : ContentPage { public PageMain() { PageMainViewModel vm = new PageMainViewModel();

我对Xamarin表单(在Android和iOS上测试)有这个问题

我有一个简单的页面

using System;

using Xamarin.Forms;

namespace BugTGR
{
    public class PageMain : ContentPage
    {
        public PageMain()
        {
            PageMainViewModel vm = new PageMainViewModel();
            this.BindingContext = vm;

            Label label1 = new Label{ Text = "Press with ICommand"};

            TapGestureRecognizer tgr = new TapGestureRecognizer();
            tgr.BindingContext = vm;
            tgr.SetBinding(TapGestureRecognizer.CommandProperty, "Tapped");
            label1.GestureRecognizers.Add(tgr);

            Label label2 = new Label { Text = "Press with Tapped"};
            TapGestureRecognizer tgr1 = new TapGestureRecognizer();
            tgr1.Tapped += async (object sender, EventArgs e) => {
                await DisplayAlert("Attention", "PRESSED WITH TAPPED", "Ok");
            };
            label2.GestureRecognizers.Add(tgr1);

            Content = new StackLayout
            {

                Children = {label1, label2}
            };
        }
    }
}
在这段代码中,我使用这个ViewModel(非常简单,只有一个命令)

然后,您可以看到,我尝试将该命令绑定到TapGestureRecognitor,然后将TGR添加到标签,但如果单击标签,则不会调用该命令

在第二个标签(label2)中,我添加了另一个TapGestureRecognitor,使用Tapped事件不绑定命令。这管用

有人可以让我知道我做错了什么

谢谢!
亚历山德罗

这是一个有效的解决方案。问题是如何创建该命令。 下面是两种方法。调用VM的命令或事件处理程序。如果您是在代码中而不是在xaml中执行此操作,我将使用vm.TappedHandler方法

namespace ButtonRendererDemo
{
    public class LabelTapPage : ContentPage
    {
        public LabelTapPage()
        {
            PageMainViewModel vm = new PageMainViewModel();
            this.BindingContext = vm;

            Label label1 = new Label { Text = "Press with ICommand" };
            TapGestureRecognizer tgr = new TapGestureRecognizer();
            label1.GestureRecognizers.Add(tgr);
            tgr.SetBinding(TapGestureRecognizer.CommandProperty, "Tapped");

            Label label2 = new Label { Text = "Press with Tapped Event" };
            TapGestureRecognizer tgr1 = new TapGestureRecognizer();
            tgr1.Tapped += async (object sender, EventArgs e) => {
                await DisplayAlert("Attention", "Tapped Event: Pressed", "Ok");
            };
            label2.GestureRecognizers.Add(tgr1);

            Label label3 = new Label { Text = "Press with TappedHandler" };
            var tapGestureRecognizer = new TapGestureRecognizer();
            tapGestureRecognizer.Tapped += async (s, e) => {
                await vm.TappedHandler();
            };
            label3.GestureRecognizers.Add(tapGestureRecognizer);


            Content = new StackLayout
            {

                Children = { label1, label2, label3 }
            };
        }
    }


    public class PageMainViewModel : INotifyPropertyChanged
    {
        ICommand tapCommand;

        public PageMainViewModel()
        {
            tapCommand = new Command(OnTapped);
        }

        public async Task TappedHandler()
        {
            await Application.Current.MainPage.DisplayAlert("Attention", "TappedHandler: Pressed", "Ok");
        }


        public ICommand Tapped
        {
            get { return tapCommand; }
        }

        async void OnTapped(object s)
        {
            await Application.Current.MainPage.DisplayAlert("Attention", "Tapped Command: Pressed", "Ok");
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

}
另外,您不需要设置tgr.BindingContext=vm;它由您的页面继承

发布后,我发现有更简单的解决方案:

删除中的“受保护”

所以佩奇可以访问它。就这样:-)


您的意思是使“设置”受保护而不是获取吗?

这是有效的解决方案。问题是如何创建该命令。 下面是两种方法。调用VM的命令或事件处理程序。如果您是在代码中而不是在xaml中执行此操作,我将使用vm.TappedHandler方法

namespace ButtonRendererDemo
{
    public class LabelTapPage : ContentPage
    {
        public LabelTapPage()
        {
            PageMainViewModel vm = new PageMainViewModel();
            this.BindingContext = vm;

            Label label1 = new Label { Text = "Press with ICommand" };
            TapGestureRecognizer tgr = new TapGestureRecognizer();
            label1.GestureRecognizers.Add(tgr);
            tgr.SetBinding(TapGestureRecognizer.CommandProperty, "Tapped");

            Label label2 = new Label { Text = "Press with Tapped Event" };
            TapGestureRecognizer tgr1 = new TapGestureRecognizer();
            tgr1.Tapped += async (object sender, EventArgs e) => {
                await DisplayAlert("Attention", "Tapped Event: Pressed", "Ok");
            };
            label2.GestureRecognizers.Add(tgr1);

            Label label3 = new Label { Text = "Press with TappedHandler" };
            var tapGestureRecognizer = new TapGestureRecognizer();
            tapGestureRecognizer.Tapped += async (s, e) => {
                await vm.TappedHandler();
            };
            label3.GestureRecognizers.Add(tapGestureRecognizer);


            Content = new StackLayout
            {

                Children = { label1, label2, label3 }
            };
        }
    }


    public class PageMainViewModel : INotifyPropertyChanged
    {
        ICommand tapCommand;

        public PageMainViewModel()
        {
            tapCommand = new Command(OnTapped);
        }

        public async Task TappedHandler()
        {
            await Application.Current.MainPage.DisplayAlert("Attention", "TappedHandler: Pressed", "Ok");
        }


        public ICommand Tapped
        {
            get { return tapCommand; }
        }

        async void OnTapped(object s)
        {
            await Application.Current.MainPage.DisplayAlert("Attention", "Tapped Command: Pressed", "Ok");
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

}
另外,您不需要设置tgr.BindingContext=vm;它由您的页面继承

发布后,我发现有更简单的解决方案:

删除中的“受保护”

所以佩奇可以访问它。就这样:-)


您的意思是使“设置”受保护而不是获取吗?

我还没有看到问题。什么不起作用?您在哪个平台上测试?另外,请确保您的Xamarin.Forms版本是最新的。@therealjohn我已经在Android和iOS上测试过了。我使用的是最新的XF版本。我做了一些其他的研究,我刚刚弄明白了,但它看起来像是尤里在我之前发布的。:)@therealjohn嘿,我领先于微软工程师,哈哈。谢谢你的关注,我还没看到这个问题。什么不起作用?您在哪个平台上测试?另外,请确保您的Xamarin.Forms版本是最新的。@therealjohn我已经在Android和iOS上测试过了。我使用的是最新的XF版本。我做了一些其他的研究,我刚刚弄明白了,但它看起来像是尤里在我之前发布的。:)@therealjohn嘿,我领先于微软工程师,哈哈。谢谢投票
public ICommand Tapped { get; set; }