我有一个完美的ObservableCollection,但是当我清除这个ObservableCollection时,我无法删除运行时出现的绑定错误:
System.Windows.Data Information: 21 : BindingExpression cannot retrieve value from null data item. This could happen when binding is detached or when binding to a Nullable type that has no value. BindingExpression:Path=Icon; DataItem='NamedObject' (HashCode=40835417); target element is 'Image' (Name=''); target property is 'Source' (type 'ImageSource')
我制作了一个小代码来重现我在下面显示的问题:(查看):
<Button Height="40" Width="40" Click="Button_Click"></Button>
<ListBox ItemsSource="{Binding ProductList}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid IsItemsHost="True"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Height="32" Source="{Binding Icon}" Stretch="Fill" Width="32"/>
<Label Grid.Row="1" Content="{Binding Description}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
public ObservableCollection<Product> ProductList { get; set; }
public void TestList()
{
ProductList = new ObservableCollection<Product>();
ProductList.Add(new Product("Product1", "pack://application:,,,/Product1.png"));
ProductList.Add(new Product("Product2", "pack://application:,,,/Product2.png"));
ProductList.Add(new Product("Product3", "pack://application:,,,/Product3.png"));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
ProductList.Clear();
ProductList.Add(new Product("Product4", "pack://application:,,,/Product4.png"));
}
我的产品类:
public class Product : INotifyPropertyChanged
{
#region "## INotifyPropertyChanged Members ##"
public event PropertyChangedEventHandler _propertyChanged;
public event PropertyChangedEventHandler PropertyChanged
{
add { this._propertyChanged += value; }
remove { this._propertyChanged -= value; }
}
protected virtual void OnPropertyChanged(string propertyName)
{
App.Current.Dispatcher.BeginInvoke((Action)delegate
{
if (this._propertyChanged != null)
this._propertyChanged(this, new PropertyChangedEventArgs(propertyName));
});
}
#endregion
public string Description
{
get { return this.description; }
set
{
this.description = value;
this.OnPropertyChanged("Description");
}
}
private string description;
public BitmapImage Icon
{
get { return this.icon; }
set
{
this.icon = value;
this.OnPropertyChanged("Icon");
}
}
private BitmapImage icon;
public Product(string desc, string iconPath)
{
Description = desc;
BitmapImage bi = new BitmapImage(new Uri(iconPath));
bi.Freeze();
Icon = bi;
}
}
单击按钮时出现错误,执行以下行: ProductList.Clear();
我做了很多测试:
单独删除列表中的项目
使用Fallback和TargetNullValue:
<Image Height="32" Source="{Binding Icon, FallbackValue='pack://application:,,,/transparent.png', TargetNullValue='pack://application:,,,/transparent.png'}" Stretch="Fill" Width="32"/>
有什么想法吗?
答案 0 :(得分:0)
尝试删除TargetNullValue和FallbackValue并查看它是否仍然存在?如果不存在,则文件的URI存在问题。
另外请记住,如果您经常引用transparent.png,则会多次将相同的图像加载到内存中。而是考虑在您的ResourceDictionary中添加一行,如下所示:
<BitmapImage UriSource="/MyApp;component/Images/transparent.png" x:Key="Transparent" PresentationOptions:Freeze="True" />
然后像这样在XAML中使用:
<Image Height="32" Source="{Binding Icon, FallbackValue={StaticResource:Transparent}, TargetNullValue={StaticResource:Transparent}" Stretch="Fill" Width="32"/>
此更改会加载您的图像一次,但会在很多地方使用它来降低内存压力。