实现Xamarin Forms上下文操作

时间:2016-07-26 08:49:38

标签: c# xamarin xamarin.forms

我正在尝试在Xamarin Forms中的列表中实现上下文操作,但无法使其工作。 我没有使用XAML,而是在代码中创建我的布局。 我正在尝试按照https://developer.xamarin.com/guides/xamarin-forms/user-interface/listview/interactivity/#Context_Actions中的步骤操作,我想在点击“修改”时推送新页面。

我清理了我的代码并删除了我努力工作的微弱尝试。

所以这是我的自定义列表单元格:

public class PickerListCell : TextCell
{
    public PickerListCell ()
    {
        var moreAction = new MenuItem { Text = App.Translate ("Edit") };
        moreAction.SetBinding (MenuItem.CommandParameterProperty, new Binding ("."));
        moreAction.Clicked += async (sender, e) => {
            var mi = ((MenuItem)sender);
            var option = (PickerListPage.OptionListItem)mi.CommandParameter;

            var recId = new Guid (option.Value);

            // This is where I want to call a method declared in my page to be able to push a page to the Navigation stack

        };
        ContextActions.Add (moreAction);
    }
}

这是我的模特:

public class OptionListItem
{
    public string Caption { get; set; }

    public string Value { get; set; }
}   

这是页面:

public class PickerPage : ContentPage
{
    ListView listView { get; set; }

    public PickerPage (OptionListItem [] items)
    {
        listView = new ListView () ;

        Content = new StackLayout {
            Children = { listView }
        };

        var cell = new DataTemplate (typeof (PickerListCell));
        cell.SetBinding (PickerListCell.TextProperty, "Caption");
        cell.SetBinding (PickerListCell.CommandParameterProperty, "Value");


        listView.ItemTemplate = cell;
        listView.ItemsSource = items;
    }

    // This is the method I want to activate when the context action is called
    void OnEditAction (object sender, EventArgs e)
    {
        var cell = (sender as Xamarin.Forms.MenuItem).BindingContext as PickerListCell;

        await Navigation.PushAsync (new RecordEditPage (recId), true);
    }

}

正如您在代码中的评论所看到的,我已经指出了我认为缺少的地方。

请帮助你们! 谢谢!

2 个答案:

答案 0 :(得分:4)

对你来说可能为时已晚,但可以帮助别人。我发现这样做的方法是在创建ViewCell时传递页面实例。

public class PickerListCell : TextCell
{
    public PickerListCell (PickerPage myPage)
    {
        var moreAction = new MenuItem { Text = App.Translate ("Edit") };
        moreAction.SetBinding (MenuItem.CommandParameterProperty, new Binding ("."));
        moreAction.Clicked += async (sender, e) => {
            var mi = ((MenuItem)sender);
            var option = (PickerListPage.OptionListItem)mi.CommandParameter;

            var recId = new Guid (option.Value);

            myPage.OnEditAction();

        };
      ContextActions.Add (moreAction);
    }
}

所以,在你的页面中:

public class PickerPage : ContentPage
{
    ListView listView { get; set; }

    public PickerPage (OptionListItem [] items)
    {
        listView = new ListView () ;

        Content = new StackLayout {
            Children = { listView }
        };

        var cell  = new DataTemplate(() => {return new PickerListCell(this); });            
        cell.SetBinding (PickerListCell.TextProperty, "Caption");
        cell.SetBinding (PickerListCell.CommandParameterProperty, "Value");


        listView.ItemTemplate = cell;
        listView.ItemsSource = items;
    }


   void OnEditAction (object sender, EventArgs e)
   {
        var cell = (sender as Xamarin.Forms.MenuItem).BindingContext as PickerListCell;

        await Navigation.PushAsync (new RecordEditPage (recId), true);
   }

}

答案 1 :(得分:1)

好的,所以在一些帖子的帮助下,特别是这个帖子https://forums.xamarin.com/discussion/27881/best-practive-mvvm-navigation-when-command-is-not-available,我来到了下面的解决方案,虽然我对它的外观并不完全满意。

我的自定义单元格现在宣布使用MessagingCenter执行命令的时间:

public class PickerListCell : TextCell
{

    public PickerListCell ()
    {
        var moreAction = new MenuItem { Text = App.Translate ("Edit") };
        moreAction.SetBinding (MenuItem.CommandParameterProperty, new Binding ("."));
        moreAction.Clicked += async (sender, e) => {
            var mi = ((MenuItem)sender);
            var option = (PickerListPage.OptionListItem)mi.CommandParameter;

            var recId = new Guid (option.Value);

            // HERE I send a request to open a new page. This looks a 
            // bit crappy with a magic string. It will be replaced with a constant or enum
            MessagingCenter.Send<OptionListItem, Guid> (this, "PushPage", recId);
        };
        ContextActions.Add (moreAction);
    }
}

在我的PickerPage构造函数中,我将此订阅添加到Messaging服务:

MessagingCenter.Subscribe<OptionListItem, Guid> (this, "PushPage", (sender, recId) => {
            Navigation.PushAsync (new RecordEditPage (recId), true);
        });

这一切都可以找到,但我不确定这是不是这样。我觉得绑定应该能够在没有Messaging Service的情况下解决这个问题,但我无法找到如何绑定到页面上的方法,只能找到模型,我不想用方法污染我的模型那些依赖于XF。

相关问题