I'm new to WPF, and I'm encountering a problem. I have a ListBox with images arranged in a floorplan, the image source is bound to a uri in the code. uri is to an embedded resource in the project. This all works fine on startup, until I have to change an image. No exceptions, but the images do not change. When I run in debug, I can see that even though the ObservableCollection items change, the mainwindow images do not.
Is this due to caching, or is it something else? I try to disable caching in the xaml, but I get the error The TypeConverter for "CacheMode" does not support converting from a string.
I'll do my best to be brief with the code and only include relevant information:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public ObservableCollection<ComputerInfo> CompListObs;
public ObservableCollection<ComputerInfo> compListObsNotifier
{
get { return CompListObs; }
set
{
CompListObs = value;
RaisePropertyChanged("compListObsNotifier");
}
}
//...
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
// This correctly loads the images from the xml and displays them on the main window:
var items = XDocument.Load(@"path to xml")
.Descendants("Computer")
.Select(i => new ComputerInfo {
MachineName = (string)i.Element("MachineName"),
Lat = (double)i.Element("Long"),
Lon = (double)i.Element("Lat"),
CurrentImage = ResourceHelper.LoadBitmapURIFromResource((string)i.Element("Img"))
}).ToList();
CompListObs = new ObservableCollection<ComputerInfo>(items);
}
public void MainTimer_Tick(object sender, EventArgs e)
{
// This runs fine and I can see the members of CompListObs are changing,
// but the images on the mainwindow are not changing.
foreach(var comp in CompListObs) { comp.CurrentImage = ResourceHelper.LoadBitmapURIFromResource("another image");
}
// INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private void RaisePropertyChanged(string propName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
public class ComputerInfo : INotifyPropertyChanged
{
public ClientInfo ClientsInfo { get; set; }
public string MachineName { get; set; }
public Uri CurrentImage { set; get; }
public double Lat { get; set; }
public double Lon { get; set; }
public Uri currentImageNotifier
{
get { return CurrentImage; }
set
{
CurrentImage = value;
RaisePropertyChanged("compListObsNotifier");
}
}
// INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public void RaisePropertyChanged(string propName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
Here is the xaml:
<ListBox ItemsSource="{Binding compListObsNotifier}">
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Path=CurrentImage}" Height="65"></Image>
</DataTemplate>
</ListBox.ItemTemplate>
<!-- after this, I place <ListBox.ItemsPanel> <ItemsPanelTemplate> and <Canvas> in the ListBox.