Dynamically Binding Label To DataSource

slink99slink99 Member ✭✭
edited June 3 in Xamarin.Forms

I have a local options SQLite table so taht the user can choose which details to display. The options are read and used to decide how to bind the text in a label. The XAML is formatted as

<ListView x:Name="wineriesView" Margin="20" HasUnevenRows="True" Grid.Row="0">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Padding="0,0,0,1">
                        <Grid Padding="5">

                            <Label Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="4" Text="{Binding Name}" />
                            <Label x:Name="bindLabel1" Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="1" Text="{Binding TxtLabel1}" />
                            <Label x:Name="bindColumn1" Grid.Row="1" Grid.Column="3" Grid.ColumnSpan="3" Text="{Binding TxtDisplay1}" />
                            <Label x:Name="bindLabel2" Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="1" Text="{Binding TxtLabel2}" />
                            <Label x:Name="bindColumn2" Grid.Row="2" Grid.Column="3" Grid.ColumnSpan="3" Text="{Binding TxtDisplay2}" />

and the code behind looks like

BindingContext = this;

        int nextlbl = 1;
        if (Constants.settings.Count > 0)
        {
            // Display options for city, county, phone, type, region and only two can be selected
            foreach (var setting in Constants.settings)
            {

                switch (setting.Type)
                {

                    case "DisplayCity":
                        if (setting.Setting == "True")
                        {
                            txtLabel1 = "City";
                            txtDisplay1 = "{Binding City}";
                            nextlbl = 2;
                        }
                        break;
                    case "DisplayCounty":
                        if (setting.Setting == "True" && nextlbl == 1)
                        {
                            txtLabel1 = "County";
                            txtDisplay1 = "{Binding County}";
                            nextlbl = 2;
                        }
                        else if (setting.Setting == "True" && nextlbl == 2)
                        {
                            txtLabel2 = "County";
                            txtDisplay2 = "{Binding County}";
                            nextlbl = 3;
                        }

with all four labels set at the bottom of that code

private string txtLabel1;
    private string txtLabel2;
    private string txtDisplay1;
    private string txtDisplay2;
    public string TxtLabel1
    {
        get { return txtLabel1; }
        set { txtLabel1 = value;
            OnPropertyChanged(nameof(txtLabel1));
        }
    }

Instead of displaying City + database contents and County + database contents (as illustrated here), I get blanks populated in the labels. What am I doing wrong?

Best Answer

  • slink99slink99 ✭✭
    Accepted Answer

    Instead of fighting with this approach and all of the changes to my models required, I went with four solid options and four separate views to be displayed based on the option. This was a much more straightforward approach that wprks well.

Answers

  • FaizalSaidaliFaizalSaidali USMember ✭✭✭

    Hi @slink99 ,
    Change your code like below,

    <Label Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="4" Text="{Binding Name}" />
    <Label x:Name="bindLabel1" Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="1" Text="{Binding Title}" />
    <Label x:Name="bindColumn1" Grid.Row="1" Grid.Column="3" Grid.ColumnSpan="3" Text="{Binding Value}" />
    <Label x:Name="bindLabel2" Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="1" Text="{Binding Count}" />
    <Label x:Name="bindColumn2" Grid.Row="2" Grid.Column="3" Grid.ColumnSpan="3" Text="{Binding Something}" />
    

    Set your contentpage BindingContext is MainPageViewModel
    Make a viewmodel class like this

        public class MainPageViewModel : BaseViewModel
        {
            private string title;
            private string value;
            private string count;
    
            public string Title
            {
                get { return title; }
                set { SetProperty(ref title, value); }
            }
            public string Value
            {
                get { return value; }
                set { SetProperty(ref value, value); }
            }
            public string Count
            {
                get { return count; }
                set { SetProperty(ref count, value); }
            }
    
            private void DoMethod()
            {
                if (Constants.settings.Count > 0)
                {
                    // Display options for city, county, phone, type, region and only two can be selected
                    foreach (var setting in Constants.settings)
                    {
    
                        switch (setting.Type)
                        {
    
                            case "DisplayCity":
                                if (setting.Setting == "True")
                                {
                                    Title = "City";
                                    Value = "{Binding City}";
                                    Count = 2;
                                }
                                break;
                            case "DisplayCounty":
                                if (setting.Setting == "True" && Count == "1")
                                {
                                    Title = "County";
                                    Value = "{Binding County}";
                                    Count = 2;
                                }
                                else if (setting.Setting == "True" && Count == "2")
                                {
                                    Title = "County";
                                    Value = "{Binding County}";
                                    Count = 3;
                                }
                                break;
                        }
                    }
                }
            }
        }
    

    BaseViewModel is inherited from INotifiedPropertyChanges. Its common for all viewmodel classes. you can get it when you create new project.

  • slink99slink99 Member ✭✭

    Thanks for the help. I left out an important piece of code. In OnAppearing, I have

    wineriesView.ItemsSource = await App.WineryManager.GetWineries(seltyp, selval, selwrs);

    which goes out to my Rest service and grabs the data to populate the grid. It pulls back City, County, Phone, Type and Region for each item to be listed, and I want the user to be able to select the two displayed. It is understood now why it displayed empty when I changed the binding to point away from the ItemsSource. How do I connect the WineryPageViewModel.cs to the data returned by the Rest service?

    Also not sure how to link the WineryPageViewModel to WineryPage.xaml.cs

  • ColeXColeX Member, Xamarin Team Xamurai
    edited June 5

    How do I connect the WineryPageViewModel.cs to the data returned by the Rest service?

    Move the logic ( grab the data from rest service ) into WineryPageViewModel class.

    public class WineryPageViewModel
    {
        public static TodoItemManager TodoManager { get; private set; }
    
        public WineryPageViewModel()
        {
            TodoManager = new TodoItemManager(new RestService());
        }
    
        public async Task<List<TodoItem>> GetData ()
        {
            return await App.TodoManager.GetTasksAsync();
        }
    }
    

    Also not sure how to link the WineryPageViewModel to WineryPage.xaml.cs

    Create a global variable WineryPageViewModel , and set it as BindingContext in constructor .

    WineryPageViewModel model;
    public WineryPage ()
    {
        InitializeComponent ();
    
        model = new WineryPageViewModel();
        BindingContext = model;
    
     }
    
  • slink99slink99 Member ✭✭
    Accepted Answer

    Instead of fighting with this approach and all of the changes to my models required, I went with four solid options and four separate views to be displayed based on the option. This was a much more straightforward approach that wprks well.

Sign In or Register to comment.