Person.cs
namespace MyWPFProject
{
public class Person
{
public string Name { get; set; }
public string Surname { get; set; }
public int Age { get; set; }
}
}
RelayCommand.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace MyWPFProject
{
public class RelayCommand : ICommand
{
private readonly Func<Boolean> _canExecute;
private readonly Action _execute;
public RelayCommand(Action execute)
: this(execute, null)
{
}
public RelayCommand(Action execute, Func<Boolean> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add
{
if (_canExecute != null)
CommandManager.RequerySuggested += value;
}
remove
{
if (_canExecute != null)
CommandManager.RequerySuggested -= value;
}
}
public Boolean CanExecute(Object parameter)
{
return _canExecute == null ? true : _canExecute();
}
public void Execute(Object parameter)
{
_execute();
}
}
}
ViewModel.cs
using System.ComponentModel;
using System.Windows.Input;
namespace MyWPFProject
{
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
ListOfPeople = new System.Collections.ObjectModel.ObservableCollection<Person>();
ListOfPeople.Add(new Person() { Name = "Michael", Surname = "Jordan", Age = 22 });
ListOfPeople.Add(new Person() { Name = "Jan", Surname = "Kowalski", Age = 21 });
ListOfPeople.Add(new Person() { Name = "Anna", Surname = "Nowak", Age = 20 });
}
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if(handler!=null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public string Name
{
get
{
return person.Name;
}
set
{
person.Name = value;
OnPropertyChanged("Name");
}
}
public string Surname
{
get
{
return person.Surname;
}
set
{
person.Surname = value;
OnPropertyChanged("Surname");
}
}
public int Age
{
get
{
return person.Age;
}
set
{
person.Age = value;
OnPropertyChanged("Age");
}
}
private void ChangeDataExecute()
{
//Ponizsze linijki nie dzialaja a debuger przez nie przechodzi jak wcisniemy buttona
ListOfPeople[1].Name = "Monika";
ListOfPeople[1].Surname = "Strucka";
ListOfPeople[1].Age = 24;
//Ponisza linijka jak sie odkomentuje to dziala
//ListOfPeople.Add(new Person() { Name = "Krzysztof", Surname = "Wozniak", Age = 20 });
}
public ICommand ChangeData { get { return new RelayCommand(ChangeDataExecute); } }
public System.Collections.ObjectModel.ObservableCollection<Person> ListOfPeople
{
get
{
return listOfPeople;
}
set
{
listOfPeople = value;
OnPropertyChanged("ListOfPeople");
}
}
private System.Collections.ObjectModel.ObservableCollection<Person> listOfPeople;
private readonly Person person;
public event PropertyChangedEventHandler PropertyChanged;
}
}
MainWindow.xaml
<Window x:Class="MyWPFProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyWPFProject"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Grid>
<StackPanel>
<ListView Name="listView" ItemsSource="{Binding Path=ListOfPeople, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=Name}"/>
<GridViewColumn Header="Surname" DisplayMemberBinding="{Binding Path=Surname}"/>
<GridViewColumn Header="Age" DisplayMemberBinding="{Binding Path=Age}"/>
</GridView>
</ListView.View>
</ListView>
<Button FontSize="20" MinHeight="30" Margin="180,20,180,0" Content="Zmień" Command="{Binding ChangeData}"/>
</StackPanel>
</Grid>
</Window>
MainWindow.xaml.cs
using System.Windows;
namespace MyWPFProject
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
No więc mam problem z bindowaniem danych. Otoż kiedy naciskam buttona to program mi uruchamia funkcję ChangeData() w ViewModelu (sprawdzalem debuggerem) i zmienia element nr 1 obiektu listOfPeople
System.Collections.ObjectModel.ObservableCollection<Person> listOfPeople;
.
Wcześniej tu miałem
List<Person>
, ale wyczytalem w tutorialach na necie, ze ten długaśny typ ma zaimplementowane bindowanie elementów tego kontenera. Bo właśnie w tym tkwi problem. Program wyświetla ładną listę osób. Jak nacisnę buttona to zmieniam element nr 1 tej listy. I to powinno się w View zaktualizować, ale tak nie się nie dzieje. Co innego jak np. w funkcji ChangeData wykonam jakieś operacje na liście (a nie na jej elementach). Wtedy ładnie aktualizuje listę. Ale jak zmienię pojedynczy element to nic się nie aktualizuje. W czym może być problem, bo już dużo kombinowałem?