在xmlns clr-namespace中找不到EventToCommandBehavior:Prism.Behaviors

时间:2017-03-26 20:45:48

标签: c# xamarin xamarin.ios xamarin.forms prism

我正在研究Xamarin.Forms项目。在Prism 6.3之前,我使用了6.2 Corcav.Behaviors包。我不需要传递参数,所以它工作得很好。但是,在AppDelegate的iOS项目中,我需要运行这一行:

Corcav.Behaviors.Infrastructure.Init();

我发表了评论: //已添加,以防止iOS链接器将行为程序集从已部署的程序包中删除。

现在EventToCommand已添加到6.3版本,因此我卸载了Corcav.Behaviors包,并实现了简单的示例。在Android中一切都很棒,但是iOS ..我有例外:

enter image description here

我认为这是因为现在我错过了这一行:Corcav.Behaviors.Infrastructure.Init();

我的例子:

查看

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:v="clr-namespace:TestApp.Mobile.Views"
             xmlns:behavior="clr-namespace:Prism.Behaviors;assembly=Prism.Forms" 
             x:Class="TestApp.Mobile.Views.StartPage">
  <v:TestGrid x:Name="MainGrid">
    <v:TestGrid.Behaviors>
      <behavior:EventToCommandBehavior EventName="OnTestTapped" 
                                        Command="{Binding OnTestTappedCommand}" 
                                        EventArgsParameterPath="Foo"/>
    </v:TestGrid.Behaviors>
  </v:TestGrid>
</ContentPage>

我的自定义网格:

public class TestGrid : Grid
{
    public event EventHandler<OnTouchedEventArgs> OnTestTapped;

    public TestGrid()
    {
        var tgr = new TapGestureRecognizer { NumberOfTapsRequired = 1 };
        tgr.Tapped += Tgr_Tapped;
        this.GestureRecognizers.Add(tgr);
    }

    private void Tgr_Tapped(object sender, EventArgs e)
    {
        OnTouchedEventArgs args = new OnTouchedEventArgs(6);
        OnTestTapped?.Invoke(sender, args);
    }
}

视图模型

public class StartPageViewModel : BindableBase
{
    private bool _canExecute;
    private ICommand onTestTappedCommand;

    public StartPageViewModel()
    {
        _canExecute = true;
    }

    public ICommand OnTestTappedCommand
    {
        get
        {
            return onTestTappedCommand ?? (onTestTappedCommand = 
                    new Command<int>((foo) => HandleEvent(foo), 
                                     (foo) => CanExecute(foo)));
        }
    }

    public async void HandleEvent(int a)
    {
        _canExecute = false;
        Status = $"Working with parameter={a}...";
        Debug.WriteLine("Test with param=" + a);
        await Task.Delay(5000);
        Status = "Done";
        _canExecute = true;
    }

    public bool CanExecute(int a)
    {
        return _canExecute;
    }
}    

..和我的自定义EventArgs:

public class OnTouchedEventArgs : EventArgs
{
    public int Foo { get; set; }

    public OnTouchedEventArgs(int foo)
    {
        Foo = foo;
    }
}   

我在Android上100%工作,在iOS上无效。

问题: 我如何在Prism.Behaviors中使用Infrastructure.Init?

修改

我认为可能会出现比我想象的更多错误...正如您在我的ViewModel中看到的那样,我正在使用来自ICommand命名空间的CommandXamarin.Forms类:

    private ICommand onTestTappedCommand;        
    public ICommand OnTestTappedCommand
    {
        get
        {
            return onTestTappedCommand ?? (onTestTappedCommand = 
                    new Command<int>((foo) => HandleEvent(foo), 
                                     (foo) => CanExecute(foo)));
        }
    }

适用于Android,但是当我更改为DelegateCommand

        return onTestTappedCommand ?? (onTestTappedCommand = 
                new DelegateCommand<int>((foo) => HandleEvent(foo), 
                                 (foo) => CanExecute(foo)));

Android也不行。然后我有一个运行时异常:

  

未处理的异常:System.Reflection.TargetInvocationException:   调用目标引发了异常。

和..项目符合,但在Start.xaml.cs我有一个错误:

  

InitializeComponent()在当前上下文中不存在

PS。请帮帮我,请不要告诉我清除解决方案/删除bin obj文件夹......它不起作用。

1 个答案:

答案 0 :(得分:2)

不需要初始化。从您显示的例外情况来看,我的建议是完成清理和重建。确保删除objbin文件夹中的所有文件。

视图模型

public DelegateCommand<string> PersonSelectedCommand => new DelegateCommand<string>(OnPersonSelectedCommandExecuted);

public ObservableRangeCollection<string> People { get; set; }

void OnPersonSelectedCommandExecuted(string name)
{
    _pageDialogService.DisplayAlertAsync("Person Selected", name, "Ok" );
}

视图

<ListView ItemsSource="{Binding People}">
    <ListView.Behaviors>
        <behaviors:EventToCommandBehavior Command="{Binding PersonSelectedCommand}" 
                                          EventName="ItemTapped"
                                          EventArgsParameterPath="Item" />
    </ListView.Behaviors>
</ListView>