Reputation: 380
I have problem with binding one item from List<>.
I have imported data from JSON file and I want go through the Array in it and show it in the TextBoxes.
Data looks like this:
{name: "ABC", Items: [ {str: "aaa"}, {str: "bbb"}, {str: "ccc"} ]}
Here is an example of C#:
public class A
{
public string Str { get; set; }
}
public class ParentA
{
public string Name { get; set; }
public List<A> Items { get; set; }
}
public class MyPage : Page
{
public ParentA ObjectParrentA { get; set; }
public int SelectedItem { get; set; }
public MyPage ()
{
ObjectParrentA = new ParentA();
// here is binding of ObjectParrentA by JSON data.
SelectedItem = 0;
this.DataContext = this;
this.InitializeComponent();
}
private void NextItem_Click(object sender, RoutedEventArgs e)
{
SelectedItem++;
}
}
And XAML:
<TextBlock Text="{Binding ObjectParrentA.Items[SelectedItem].Str}" />
<Button Name="NextItem" Click="NextItem_Click" Content="Next Item" />
At the start in the TextBox should be shown "aaa", after click the Next Item button there should be "bbb", etc...
Now the TextBlock is blank. I think that there must be problem in "Binding ObjectParrentA.Items[SelectedItem].Str", but I don't have too much experiences with binding.
Do you have any hints, how to achieve this? Thank you.
Upvotes: 0
Views: 1079
Reputation: 4592
I have changed it slightly to be a little more MVVM. You will need to refactor it into a page:
public class A
{
public string Str { get; set; }
}
public class ParentAViewModel : INotifyPropertyChanged
{
private int _currentIndex;
public ParentAViewModel()
{
Items = new List<A>();
}
public string Name { get; set; }
public List<A> Items { get; set; }
public int CurrentIndex
{
get
{
return _currentIndex;
}
set
{
_currentIndex = value;
OnPropertyChanged();
OnPropertyChanged(nameof(CurrentItem));
}
}
public string CurrentItem => Items[CurrentIndex].Str;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public partial class MainWindow : Window
{
public ParentAViewModel ObjectParrentA { get; set; }
public int SelectedItem { get; set; }
public MainWindow()
{
ObjectParrentA = new ParentAViewModel();
ObjectParrentA.Items.Add(new A() { Str = "1" });
ObjectParrentA.Items.Add(new A() { Str = "2" });
ObjectParrentA.Items.Add(new A() { Str = "3" });
// here is binding of ObjectParrentA by JSON data.
SelectedItem = 0;
this.DataContext = this;
InitializeComponent();
}
private void NextItem_Click(object sender, RoutedEventArgs e)
{
ObjectParrentA.CurrentIndex++;
}
}
XAML:
<StackPanel>
<TextBlock Text="{Binding ObjectParrentA.CurrentItem}" />
<Button Name="NextItem" Click="NextItem_Click" Content="Next Item" />
</StackPanel>
WPF works at its best when you bind to observable properties - methods can be tricky. It's common to add a ViewModel to facilitate this, so you don't pollute your model classes with objects that are only relevant to the view.
Here, we are watching the property CurrentItem via the binding. When the button is clicked, we inform WPF that the CurrentItem has changed via the OnPropertyChanged(nameof(CurrentItem)) of the CurrentIndex setter, this then rebinds the view to the new value.
I hope that makes sense. Good luck.
Upvotes: 1