Forum Xamarin.Forms

Announcement:

The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

Binding ViewModel to custom UI not Binding Items to control

BenjaminTooleBenjaminToole USMember ✭✭✭

I have a home Page that contains a custom control 'MenuItemControl'. This control contains a formatted StackLayout with some labels, that I want to display the text that is being bound to it which works until I bind the MenuItemViewModel to it, then It does not bind to the custom control, and the text is not updating. It seems like the custom control contains the binding context, but the bindings don't seem to take effect. What is wrong with what I'm doing? This seems like it should be a piece of cake:

Home page :

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:local="clr-namespace:TamarianApp;assembly=TamarianApp" xmlns:controls="clr-namespace:XLabs.Forms.Controls;assembly=XLabs.Forms"  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="TamarianApp.Home">
<Grid>
    <StackLayout x:Name="main_view">
        <ScrollView>
            <StackLayout>


                <!-- new menu --> 

                <local:MenuItemControl x:Name="lengthMenuItem" Title="{Binding Title}" SubTitle="{Binding SubTitle}" Test="{Binding teststring}"></local:MenuItemControl>   
                <BoxView Margin="0, -7, 0, 0" HorizontalOptions="FillAndExpand" HeightRequest="1" BackgroundColor="#f1f1f1"></BoxView>
            </StackLayout>
        </ScrollView>
        <StackLayout BackgroundColor="#fafafa"  HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
            <BoxView HorizontalOptions="FillAndExpand"  HeightRequest="3" BackgroundColor="#f1f1f1"></BoxView>
        </StackLayout>
    </StackLayout>
    <ActivityIndicator x:Name="loading_activity" IsRunning="false" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"></ActivityIndicator>
</Grid>

</ContentPage>

Home page C#:

public partial class Home : ContentPage
    {
        public MenuItemModelView modelview;
        public string teststring { get; set; } = "this is a test"; 
        public Home()
        {
            InitializeComponent();

            modelview = new MenuItemModelView
            {
                PageTo = new LengthPage(),
                Title = "Length",
                SubTitle = "10"
            };


            lengthMenuItem.BindingContext = modelview;


            NavigationPage.SetHasNavigationBar(this, true);
            Title = "Home";

        }
    }
}

Custom control (MenuItemControl):

    public class MenuItemControl : ContentView
    {
        StackLayout main;
        Label title, subTitle;
        public Command itemClicked;
        public static  BindableProperty ItemClickedCommandProperty = BindableProperty.Create("ItemClicked", typeof(MenuItemControl), typeof(Command),null, BindingMode.TwoWay);
        public static readonly BindableProperty TitleProperty = BindableProperty.Create("Title", typeof(MenuItemControl), typeof(string), null, defaultBindingMode:BindingMode.TwoWay);
        public static readonly BindableProperty SubTitleProperty = BindableProperty.Create("SubTitle", typeof(MenuItemControl), typeof(string), null, defaultBindingMode: BindingMode.TwoWay);
        public static BindableProperty TestProperty = BindableProperty.Create("Test", typeof(MenuItemControl), typeof(string),null, BindingMode.TwoWay);

        public string Test
        {
            get
            {
                return (string)GetValue(TestProperty);
            }
            set
            {
                SetValue(TestProperty, value);
            }
        }

        public string Title
        {
            get
            {
                return (string)GetValue(TitleProperty);
            }
            set
            {
                title.Text = value;
                SetValue(TitleProperty, value);
            }
        }

        public string SubTitle
        {
            get
            {
                return (string)GetValue(SubTitleProperty);
            }
            set
            {
                subTitle.Text = value; 
                SetValue(SubTitleProperty, value);
            }
        }


        public Command ItemClickedCommand
        {
            get
            {
                return (Command)GetValue(ItemClickedCommandProperty);
            }
            set
            {
                itemClicked = value; 
                SetValue(ItemClickedCommandProperty, value);
            }
        }

        public MenuItemControl()
        {
            TapGestureRecognizer itemTapped = new TapGestureRecognizer();
            itemTapped.Tapped += ItemWasClicked;

            BoxView line = new BoxView
            {
                HeightRequest = 1,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                BackgroundColor = Color.FromHex("#f1f1f1")
            };

            title = new Label
            {
                Text = this.Title,
                Margin = new Thickness(10, 2, 0, 0),
                HorizontalOptions = LayoutOptions.StartAndExpand,
            };

             subTitle = new Label
            {
                Text = this.SubTitle,
                Margin = new Thickness(10, 2, 10, 0),
                FontSize = 14,
                TextColor = Color.FromHex("#c1c1c1"),
                HorizontalOptions = LayoutOptions.End,
            };

            Image image = new Image
            {
                HorizontalOptions = LayoutOptions.End,
                Source = "icons/blue/next",
                WidthRequest = 20
            };
            main = new StackLayout()
            {

                Children = {

                    line,
                    new StackLayout{
                        Orientation = StackOrientation.Horizontal,
                        HorizontalOptions = LayoutOptions.Fill,
                        Padding = new Thickness(10),
                        Children ={

                            title,
                            subTitle,
                            image
                        }
                    }
                }
            };
            main.GestureRecognizers.Add(itemTapped);
            Content = main;
        }

        public void ItemWasClicked(object sender, EventArgs e)
        {
            itemClicked.CanExecute(true);
        }
    }

View model (MenuItemViewModel):

public class MenuItemModelView : ViewModel
    {
        private string title { get; set; }
        private string subtitle { get; set; } 
        private Page pageto { get; set; } 
        private Command MenuItemSelectedCommand { get; set; }

        public MenuItemModelView()
        {
            MenuItemSelectedCommand = new Command(async() => await OnMenuItemSelectedCommand());
        }

        public string Title
        {
            get
            {
                return title;
            }
            set
            {
                if (value != title)
                {
                    title = value;
                    OnPropertyChanged();
                }
            }
        }

        public string SubTitle
        {
            get
            {
                return subtitle;
            }
            set
            {
                if (value != subtitle)
                {
                    subtitle = value;
                    OnPropertyChanged();
                }
            }
        }

        public Page PageTo
        {
            get
            {
                return pageto;
            }
            set
            {
                if (value != pageto)
                {
                    pageto = value;
                    OnPropertyChanged();
                }
            }
        }

        public async Task<bool> OnMenuItemSelectedCommand()
        {
            if (PageTo != null)
            {
                await CurrentPage.Navigation.PushAsync(PageTo);
                return true; 
            }
            return false; 
        }
    }
Sign In or Register to comment.