我正在尝试在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);
}
}
正如您在代码中的评论所看到的,我已经指出了我认为缺少的地方。
请帮助你们! 谢谢!
答案 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。