I need some help to correctly bind an ObservableCollection to xaml. I can bind the data correctly but when the data changed, the changes did not reflect on the screen. I have read related blogs and seemed to have understood, but when trying to apply what I know into my own sample, it does not work quite as I have thought.
I have 2 classes Fruits and Fruit, where Fruits is a observablecollection of fruit which implements INotifyPropertyChanged
namespace TestCommand.Models
{
public class Fruit:INotifyPropertyChanged
{
private string _fruitname;
public string FruitName
{ get
{
return _fruitname;
}
set
{
if (_fruitname!=value)
{
_fruitname = value;
OnPropertyChanged("FruitName");
}
}
}
private string _fruitcolor;
public string FruitColor
{
get
{
return _fruitcolor;
}
set
{
if (_fruitcolor != value)
{
_fruitcolor = value;
OnPropertyChanged("FruitColor");
}
}
}
private bool _selected;
public bool bSelected
{
get
{
return _selected;
}
set
{
if (_selected != value)
{
_selected = value;
OnPropertyChanged("bSelected");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string name)
{
if (PropertyChanged!=null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
}
namespace TestCommand.Models
{
public class Fruits
{
private static ObservableCollection<Fruit> _fruitList;
public static void Add(string f, string c)
{
_fruitList.Add(new Fruit
{
FruitName = f,
FruitColor = c,
bSelected = false
});
}
static Fruits()
{
_fruitList = new ObservableCollection<Fruit>();
_fruitList.Add(new Fruit
{
FruitName = "Mango",
FruitColor = "Yellow",
bSelected = false
});
_fruitList.Add(new Fruit
{
FruitName = "Mango",
FruitColor = "Yellow",
bSelected = false
});
_fruitList.Add(new Fruit
{
FruitName = "Water Melon",
FruitColor = "Green",
bSelected = false
});
_fruitList.Add(new Fruit
{
FruitName = "Apple",
FruitColor = "Red",
bSelected = false
});
_fruitList.Add(new Fruit
{
FruitName = "Banana",
FruitColor = "Yellow",
bSelected = false
});
_fruitList.Add(new Fruit
{
FruitName = "Orange",
FruitColor = "Orange",
bSelected = false
});
}
public static ObservableCollection<Fruit> getAllFruit(bool bSelected = false)
{
var result = (bSelected ?
_fruitList.Where(x => x.bSelected = true).ToList<Fruit>()
: _fruitList.ToList<Fruit>());
return new ObservableCollection<Fruit>(result);
}
}
}
My xaml:
<Window x:Class="TestCommand.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:TestCommand"
xmlns:MyCommands='clr-namespace:TestCommand.Commands'
mc:Ignorable="d"
Title="MainWindow"
Height="350"
Width="525">
<StackPanel Orientation='Vertical' Margin='10'>
<ListBox x:Name='MyList' ItemTemplate='{StaticResource FruitTemp}'>
</ListBox>
<Button x:Name='AddFruit'
Height='auto'
Width='auto'
Content='Add New Fruit 2'
Margin='0,10,0,0'
Command='{x:Static MyCommands:TestButtonCommand.AddFruit}'>
<Button.CommandBindings>
<CommandBinding Command='{x:Static MyCommands:TestButtonCommand.AddFruit}'
Executed='CommandBinding_Executed'
CanExecute='CommandBinding_CanExecute' />
</Button.CommandBindings>
</Button>
</StackPanel>
</Window>
and code behind:
namespace TestCommand
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MyList.ItemsSource = Fruits.getAllFruit();
}
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
Fruits.Add("Durian", "Green");
}
private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
}
}
My ItemTemplate
<Application x:Class="TestCommand.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestCommand"
StartupUri="MainWindow.xaml">
<Application.Resources>
<DataTemplate x:Key='FruitTemp'>
<StackPanel Orientation='Horizontal'
Margin='5'>
<TextBlock x:Name='tbName'
Text='{Binding FruitName}'
Margin='10,0,0,0'
Width='100'/>
<TextBlock x:Name='tbColor'
Text='{Binding FruitColor}'
Margin='10,0,0,0'
Width='100' />
<!--<CheckBox x:Name='cbSelected'
Content='Selected'
Checked='{Binding bSelected}' />-->
</StackPanel>
</DataTemplate>
</Application.Resources>
</Application>
When I clicked on the button, I saw item added to the collection but the collection was not refreshed on the list. I must have not tied the collection correctly or may have missed something as I am very new to wpf.
Your help to point out my overlook is very much appreciated.