【发布时间】:2016-11-28 02:27:59
【问题描述】:
我有一个运行良好的 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;
}
}
单击按钮并执行以下行时出现错误: 产品列表.清除();
我做了很多测试:
从列表中逐个删除项目
-
使用 Fallback 和 TargetNullValue:
<Image Height="32" Source="{Binding Icon, FallbackValue='pack://application:,,,/transparent.png', TargetNullValue='pack://application:,,,/transparent.png'}" Stretch="Fill" Width="32"/>
有什么想法吗?
【问题讨论】:
-
您尝试过 ProductList.ClearItems() 吗? msdn.microsoft.com/en-us/library/ms654925(v=vs.110).aspx
-
我可以毫无问题地清除产品列表。错误不会重现。
-
INotifyPropertyChanged的实现看起来有点混乱,甚至可能没有必要,除非您要动态更改列表中各个产品的描述和/或图标。跨度> -
“.Clear()”函数只在绑定中返回恼人的运行时错误。示例中可能不需要 INotifyPropertyChanged,但它不会影响我遇到的问题。
标签: wpf xaml data-binding observablecollection