0

I have a ListView shown below. How can I bind dictionary to ListView Itemsource so that my label as key and ENtry has value?

I don't know How to proceed further

I tried with this but I am getting null reference exception

<ListView x:Name="ItemsListView" VerticalOptions="FillAndExpand" SeparatorVisibility="None" HasUnevenRows="true" ItemsSource="{Binding dictionary}">
  <ListView.ItemTemplate>
    <DataTemplate>
      <ViewCell>
        <Grid>
          <Label Text="{Binding Key}" Grid.Row="1" Grid.Column="0" Style="{DynamicResource lblTitle}" />
          <Entry x:Name="test" Text="{Binding Value}" Grid.Row="1" Grid.Column="1" />
        </Grid>

      </ViewCell>

    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

view model

public List<string> Key
{
    get { return key; }
    set
    {
        SetProperty(ref key, value);

    }
}

public List<Int32> Value
{
    get { return val; }
    set
    {
        SetProperty(ref val, value);
    }
}**

for (int i = 0; i < AllProductsList.Count; i++)
{
    Value.Add(0);
    //Value = new ObservableCollection<Int32>(val);
}

for (int j = 0; j < AllProductsList.Count; j++)
{
    for (int k = 0; k < Value.Count; k++)
    {
        if (j == k)
        {
            dictionary[Key[j]] = Value[k];
        }
    }
barbsan
  • 3,418
  • 11
  • 21
  • 28
  • expected result is for example. item1 10 item2 20 item3 30 item4 40 The list count will dynamically change as per requirement – Ashwini Shetty Aug 07 '19 at 09:18
  • 1
    If you are getting a NullReferenceException, please include the Stack trace for that, so we can help you narrow down which part of your code fails – Cheesebaron Aug 07 '19 at 10:54
  • Where do you initialize `dictionary`? Where are these `for` loops? – barbsan Aug 07 '19 at 12:20
  • What type of source data, could you show it ? Maybe you can convert source data to ViewModel can be directly used in ListView . – Junior Jiang Aug 08 '19 at 02:51

2 Answers2

1

Because not knowing what type of your source data,if source data is a json type from web api, you can refer to this discussion to convert json object to ViewMidel.

In ListView ,ItemSource can be used as follow:

DictionaryModel.cs:

public class DictionaryModel : INotifyPropertyChanged
{
    string key= string.Empty;
    public string Key
    {
        get { return key; }
        set { SetProperty(ref key, value); }
    }

    Int32 valueint = 0;
    public Int32 Value
    {
        get { return valueint; }
        set { SetProperty(ref valueint, value); }
    }

     protected bool SetProperty<T>(ref T backingStore, T value,
        [CallerMemberName]string propertyName = "",
        Action onChanged = null)
    {
        if (EqualityComparer<T>.Default.Equals(backingStore, value))
            return false;

        backingStore = value;
        onChanged?.Invoke();
        OnPropertyChanged(propertyName);
        return true;
    }

    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        var changed = PropertyChanged;
        if (changed == null)
            return;

        changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}

ViewModel.cs:

public class ViewModel
{

   public IList<DictionaryModel> DictionaryModels { get; private set; }

   public ViewModel()
   {
      DictionaryModels = new List<DictionaryModel>();

      // set demo data 
      DictionaryModels.Add(new DictionaryModel
      {
           Key = "Baboon",
           Value= 1,
      });

      DictionaryModels.Add(new DictionaryModel
      {
           Key = "Capuchin",
           Value= 2,
      });

   }

}

Then in ContenPage.cs , binding ViewModel:

BindingContext = new ViewModel();

Finally in Xaml :

<ListView x:Name="ItemsListView" VerticalOptions="FillAndExpand" SeparatorVisibility="None" HasUnevenRows="true" ItemsSource="{Binding DictionaryModels}">
  <ListView.ItemTemplate>
    <DataTemplate>
      <ViewCell>
        <Grid>
          <Label Text="{Binding Key}" Grid.Row="1" Grid.Column="0" Style="{DynamicResource lblTitle}" />
          <Entry x:Name="test" Text="{Binding Value}" Grid.Row="1" Grid.Column="1" />
        </Grid>

      </ViewCell>

    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>
Junior Jiang
  • 12,430
  • 1
  • 10
  • 30
0

If the ItemSource is a Dictionary, then simply Binding "Key" and "Value" should work. I guess that is what you did. But You don't need to create properties "Key" and "Value". So please remove that..

//Remove these Properties
    public List<string> Key
            {
                get { return key; }
                set
                {
                    SetProperty(ref key, value);

                }
            }
            public List<Int32> Value
            {
                get { return val; }
                set
                {
                    SetProperty(ref val, value);

                }
            }**

What you did in your Xaml is correct.

<Grid>
      <Label Text="{Binding Key}" Grid.Row="1" Grid.Column="0" Style="{DynamicResource lblTitle}" />
      <Entry x:Name="test" Text="{Binding Value}" Grid.Row="1" Grid.Column="1" />
    </Grid>

Label will show the Keys and Entry will show the value. Now, make the ItemSource of your List Binding your Dictionary(instead of the IList/List). If you set the ItemSource= "{Binding YourDictionary}", then you can bind Key and Value as you did(Provided, YourDictionary is of type Dictionary<string,string>).

DGN
  • 702
  • 3
  • 12