2016-07-24 2 views
0

У меня есть ObservableCollection, который прекрасно работает, но я не могу удалить связывающую ошибку, которая появляется во время выполнения, когда я очищаю этот ObservableCollection:Binding Ошибка выполнения клирингового 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

Вы попробовали ProductList.ClearItems()? https://msdn.microsoft.com/en-us/library/ms654925(v=vs.110).aspx – AVK

+0

Я могу удалить список продуктов без проблем. Ошибка не воспроизводится. – jsanalytics

+0

Ваша реализация 'INotifyPropertyChanged' выглядит немного грязной, и она может даже не понадобиться, если вы не будете динамически изменять описание и/или значок для отдельных продуктов в своем списке. – jsanalytics

ответ

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"/> 

Это изменение будет загрузить изображение один раз, но использовать его во многих местах уменьшающихся давлений памяти.

+0

Спасибо, предложение, очень полезно. В любом случае ошибка сохраняется. –

Смежные вопросы