2016-07-26 41 views
0

我想在Xamarin Forms的列表中實現上下文動作,但無法讓它工作。 我不使用XAML,而是在代碼中創建我的佈局。 我試圖按照https://developer.xamarin.com/guides/xamarin-forms/user-interface/listview/interactivity/#Context_Actions中的步驟操作,並且當點擊「編輯」時我想推新頁面。實現Xamarin Forms上下文動作

我清理了我的代碼,並刪除了我無法企及的工作。

所以這是我的自定義列表格:

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

好的,所以在一些帖子的幫助下,特別是這一個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構造函數添加此訂閱的信息服務:

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

所有這一切工作只是發現,但我不確定這是否是它打算的方式。我覺得綁定應該能夠在沒有消息服務的情況下解決這個問題,但我無法找到如何綁定到頁面上的方法,只能綁定到模型,而且我不想用方法污染我的模型與XF有依賴關係。

1

對你而言可能已經太晚了,但可以幫助別人。我發現這樣做的方式是在創建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); 
    } 

}