3

I have listview that have two views manipulated dynamically label and button, and I am trying to access button click to go to the details page on button click.

below is my custom ViewCell

protected override async void OnAppearing()
{
    listClass.ItemsSource = list;
    listClass.ItemTemplate = new DataTemplate(typeof(ItemTemplateViewCell )); 
}

public class ItemTemplateViewCell : ViewCell
{

    Label NameLbl = new Label();
    StackLayout sLayout = new StackLayout ();
    Button btnViewcell = new Button {Text = "Show class details"};
    public ItemTemplateViewCell()
    {
        NameLbl.SetBinding(Label.TextProperty, "Name");
        sLayout.Children.Add(NameLbl);
        btnViewcell.Clicked += (s, e) =>
        {
            // Navigation.PushAsync(new Home()); //I can not using this line 
            // does not exist in the current context, why cant i navigate to 
            // another page from inside datatemplate in List view
        };
        sLayout.Children.Add(btnViewcell);
        this.View = sLayout;
    }
}
1
  • I hope the comment behind Navigation.PushAsync(... is on one line in your actual code? Please put it also on one line then here, since that does makes a huge difference in coding Commented Sep 13, 2017 at 14:17

4 Answers 4

3

You can pass the Navication to ViewCell through constructor:

    public class ItemTemplateViewCell : ViewCell
    {
        // Navigation Mermber
        INavigation MyNavigation;
        Label NameLbl = new Label();
        StackLayout sLayout = new StackLayout ();
        Button btnViewcell = new Button {Text = "Show class details"};
        public ItemTemplateViewCell(INavigation navigation)
        {
            MyNavigation = navigation;
            NameLbl.SetBinding(Label.TextProperty, "Name");
            sLayout.Children.Add(NameLbl);
            btnViewcell.Clicked += ButtonShowDetails_Clicked;
            sLayout.Children.Add(btnViewcell);
            this.View = sLayout;
        }

        private void ButtonShowDetails_Clicked(object sender, EventArgs e)
        {                                                  
             MyNavigation.PushAsync(new Home());
        }
    }

Then pass the Navication through the delegate Function

    protected override async void OnAppearing()
    {
       listClass.ItemsSource = list;
       listClass.ItemTemplate = new DataTemplate(Function) ; 
    }

    public object Function()
    {
        return new ItemTemplateViewCell (Navigation);
    }

Then you can access the Navigation object in ViewCell

Sign up to request clarification or add additional context in comments.

1 Comment

i tried it and its working like a charm ,thanks so much Husam Zidan ,Delegates is fantastic
1

Simply you are able to use CommandParameterProperty with binding :

Example:

ListViewClass.ItemTemplate = new DataTemplate(() =>
{
  var GoHomeButton = new Button { Text = "Go Home", HorizontalOptions = LayoutOptions.StartAndExpand };
  GoHomeButton.SetBinding(Button.CommandParameterProperty, new Binding("Name"));
  GoHomeButton.Clicked += Gohome;
//return new view cell 
 }
    private void Gohome(object sender, EventArgs e)
    {      
            Navigation.PushAsync(new Home());
    }

For more info check the following Link:

http://www.c-sharpcorner.com/blogs/handling-child-control-event-in-listview-using-xamarinforms1

Comments

0

What I think is going wrong is that you are performing an action immediately in the initialization of the class. You should split it up so like below. Another issue is that you do initialization of variables outside of the methods. This might go okay, but I prefer the below code:

public class ItemTemplateViewCell : ViewCell
{

    Label nameLbl;
    StackLayout sLayout;
    Button btnViewcell;
    public ItemTemplateViewCell()
    {
        nameLbl = new Label()
        sLayout = new StackLayout ()
        btnViewcell = new Button {Text = "Show class details"};

        NameLbl.SetBinding(Label.TextProperty, "Name");
        sLayout.Children.Add(NameLbl);
        btnViewcell.Clicked += OnButtonClicked;
        sLayout.Children.Add(btnViewcell);
        this.View = sLayout;
    }

    void OnButtonClicked(object sender, EventArgs e)
    {
        Navigation.PushAsync(new Home()); 
    }
}

I think this should work in your case but I can't be sure. I don't think what you posted is one on one your code since I don't see any initialization of s and e in your code and as mentioned in the comments the comment in your code would cause issues if you really put it as in the question. Also you don't share the code of the Home class. Something might be wrong at that end.

1 Comment

He don't needs any initialization of s and e. He is using a Lambda expression: stackoverflow.com/questions/6531970/…
0

Navigation is not available inside of a ViewCell, this means you can't access it right from your ViewCell. But this should work:

App.Current.MainPage.Navigation.PushAsync(new Home());

The whole code:

protected override async void OnAppearing()
{
    listClass.ItemsSource = list;
    listClass.ItemTemplate = new DataTemplate(typeof(ItemTemplateViewCell )); 
}

public class ItemTemplateViewCell : ViewCell
{

    Label NameLbl = new Label();
    StackLayout sLayout = new StackLayout ();
    Button btnViewcell = new Button {Text = "Show class details"};
    public ItemTemplateViewCell()
    {
        NameLbl.SetBinding(Label.TextProperty, "Name");
        sLayout.Children.Add(NameLbl);
        btnViewcell.Clicked += (s, e) =>
        {
            App.Current.MainPage.Navigation.PushAsync(new Home());
        };
        sLayout.Children.Add(btnViewcell);
        this.View = sLayout;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.