M Yil
M Yil

Reputation: 957

Xamarin Forms - Bind UI controls to object properties (those objects are in a list)

In the codebehind I loop through a list that is defined in the viewmodel. For each item I check what type of Control (Entry, Picker etc..) I need to create. The problem is that I don't know how to bind those controls with properties from objects in the list defined in the viewmodel..

My code:

        // Create controls dynamically
        for (int i = 0; i < (BindingContext as CheckListEditViewModel).CheckListItems.Count; i++)
        {
            var item = (BindingContext as CheckListEditViewModel).CheckListItems[i];

            var description = new Label()
            {
                Text = item.Description
            };
            stack.Children.Add(description);

            if ((item.ChecklistItemType == Domain.ChecklistItemType.Number))
            {
                var numerEntry = new Entry();
                numerEntry.Keyboard = Keyboard.Numeric;

                numerEntry.SetBinding(Entry.TextProperty, "item.Value"); // How should I do this??

                stack.Children.Add(numerEntry);
            }
            else if ((item.ChecklistItemType == Domain.ChecklistItemType.Email))
            {
                var numerEntry = new Entry();
                numerEntry.Keyboard = Keyboard.Email;
                stack.Children.Add(numerEntry);
            }
        }

        Content = stack;

How should I bind those UI controls with properties in the item object? (Ps: the item object is taken from a list)

Upvotes: 1

Views: 151

Answers (2)

Cherry Bu - MSFT
Cherry Bu - MSFT

Reputation: 10346

According to your description, you loop item from List, and want to bind every item to UI, I do some code according to your code, you can take a look:

 public Page33()
    {
        InitializeComponent();

        this.BindingContext = new CheckListEditViewModel();

        StackLayout stack = new StackLayout();

        for(int i=0;i<(BindingContext as CheckListEditViewModel).CheckListItems.Count;i++)
        {
            var item = (BindingContext as CheckListEditViewModel).CheckListItems[i];

            var description = new Label()
            {
                Text = item.Description
            };
            stack.Children.Add(description);

            if ((item.ChecklistItemType == "Number"))
            {
                var numerEntry = new Entry();
                numerEntry.Keyboard = Keyboard.Numeric;

                numerEntry.SetBinding(Entry.TextProperty, new Binding("value",BindingMode.TwoWay,source:item));

                stack.Children.Add(numerEntry);
            }
            else if ((item.ChecklistItemType == "Email"))
            {
                var numerEntry = new Entry();
                numerEntry.Keyboard = Keyboard.Email;
                numerEntry.SetBinding(Entry.TextProperty, new Binding("value", BindingMode.TwoWay, source: item));
                stack.Children.Add(numerEntry);
            }
        }
        this.Content = stack;
    }
}

public class CheckListEditViewModel:ViewModelBase
{
    private List<EditModel> _CheckListItems;
    public List<EditModel> CheckListItems
    {
        get { return _CheckListItems; }
        set
        {
            _CheckListItems = value;
            RaisePropertyChanged("CheckListItems");
        }
    }
    public CheckListEditViewModel()
    {
        CheckListItems = new List<EditModel>();
        CheckListItems.Add(new EditModel() {Description="one model",ChecklistItemType="Email",value="[email protected]" });
        CheckListItems.Add(new EditModel() { Description = "two model", ChecklistItemType = "Number",value="12345" });
        CheckListItems.Add(new EditModel() { Description = "three model", ChecklistItemType = "Email",value="[email protected]" });
        CheckListItems.Add(new EditModel() { Description = "four model", ChecklistItemType = "Number",value="567" });
    }
}
public class EditModel
{
    public string Description { get; set; }
    public string ChecklistItemType { get; set; }
    public string value { get; set; }
}

I set current ContentPage BindingContext = new CheckListEditViewModel(), then loop every item from List, then the item is the source of current control.

enter image description here

Upvotes: 0

Paul Kertscher
Paul Kertscher

Reputation: 9703

The object item is unknown to your numberEntry object. You cannot expect SetBinding to magically know what you mean with item - could be anything. In order to make sense of SetBinding, the BindingContext of your control has to be set. In your case, it'd be sensible to set it to item

var numerEntry = new Entry();
numerEntry.Keyboard = Keyboard.Numeric;

numerEntry.SetBinding(Entry.TextProperty, path: "Value");
numerEntry.BindingContext = item;

stack.Children.Add(numerEntry);

Since the path parameter (written explicitly for clarification) indicates a path to a property relative to the BindingContext, the "item.Value" has to be changed to "Value".

Upvotes: 1

Related Questions