2016-07-26 23 views
0

Ich versuche, Kontextaktionen auf meiner Liste in Xamarin Forms zu implementieren, kann sie aber nicht ausführen. Ich verwende nicht XAML, sondern mein Layout im Code. Ich versuche, die Schritte in https://developer.xamarin.com/guides/xamarin-forms/user-interface/listview/interactivity/#Context_Actions zu folgen, und ich möchte eine neue Seite drücken, wenn "Bearbeiten" angeklickt wird.Implementieren von Xamarin Forms-Kontextaktionen

Ich räumte meinen Code auf und entfernte meine schwachen Versuche, Dinge zum Laufen zu bringen.

Das ist also meine benutzerdefinierte Liste Zelle:

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); 
    } 
} 

Und hier ist mein Modell:

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

    public string Value { get; set; } 
} 

Und dies ist die Seite:

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); 
    } 

} 

Wie Sie sehen können, Meine Kommentare im Code habe ich angegeben, wo ich glaube, dass Dinge fehlen.

Bitte assistieren Sie Jungs! Danke!

Antwort

0

Ok, also mit Hilfe von einigen Posts, speziell diesem https://forums.xamarin.com/discussion/27881/best-practive-mvvm-navigation-when-command-is-not-available, kam ich zu der folgenden Lösung, obwohl ich nicht vollkommen mit der Art zufrieden bin, wie es aussieht.

Meine benutzerdefinierte Zelle jetzt ankündigt, wenn ein Befehl MessagingCenter ausgeführt wird unter Verwendung von:

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); 
    } 
} 

Und in meinem PickerPage Konstruktor ich dieses Abonnement für den Messaging-Dienst hinzugefügt:

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

dies nur Alle Werke finde, aber ich bin mir nicht sicher, ob das so ist, wie es beabsichtigt war. Ich habe das Gefühl, dass die Bindung in der Lage sein sollte, dies ohne den Messaging Service zu lösen, aber ich kann nicht herausfinden, wie man an eine Methode auf der Seite bindet, nur an ein Modell, und ich möchte mein Modell nicht mit Methoden verunreinigen die Abhängigkeiten von XF haben.

1

Wahrscheinlich ist zu spät für Sie, kann aber anderen helfen. Die Methode, die ich gefunden habe, besteht darin, die Instanz der Seite beim Erstellen der ViewCell zu übergeben.

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); 
    } 
} 

also in Ihre Seite ein:

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); 
    } 

} 
Verwandte Themen