Низкая производительность WPF - много DataItem = предупреждения о нулевой привязке
У меня есть элемент управления деревом, который показывает очень плохую производительность, и яЯ пытаюсь отследить источник проблемы.
Я пытаюсь понять, важны ли такие предупреждения, как следующее:
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=ContextMenu.IsOpen; DataItem=null; target element is 'MultipleSelectionTreeViewItem' (Name=''); target property is 'NoTarget' (type 'Object')
Производительность обновления содержимого дерева, даже когда все эти диагнозы выключены, действительно ужасна (более секунды, чтобы заново заполнить ~ 300 элементов), и именно это заставило меня посмотреть на вывод трассировки.
Эти предупреждения издаются дюжиной для каждого клика в моем дереве, и когда я переключаю дерево, чтобы отобразить различное содержимое, возникает несколько сотен таких предупреждений. Однако содержимое дерева всегда отображается правильно, поэтому контекст данных должен быть установлен на ноль только временно.
Я поставил явную привязку дляDataContext
с конвертером значений, чтобы попытаться увидеть, что происходит.
...
... но значение никогда не кажется равным нулю, поступающему туда.
Я мог бы установить запасное значение для всех привязок, чтобы избавиться от этих предупреждений, но это добавляет много ненужного беспорядка в xaml и похоже на это »скрывает проблему, а не решает ее (предполагая, что это даже проблема!).
Итак, мой вопрос:
Эти диагнозы могут вызвать проблемы с производительностью?Если да, то будет ли предоставление запасных значений иметь какое-то значение для производительности при отключении диагоналей?Если так, то есть ли лучший способ сделать это, чем заполнить xaml crud?редактировать
Использование резервных значений выглядит какрешение в любом случае, потому что этоТакже не удалось найти ресурсы:
System.Windows.ResourceDictionary Warning: 9 : Resource not found; ResourceKey='Img_Folder_Closed_Ex'
Это'Как будто он забывает все в словаре ресурсов, генерирует все эти ложные ошибки, а затем снова запоминает все и отображает ок.
редактировать
Хорошо ямы сузили это немного дальше, закомментировав все привязки и положив их обратно один за другим и решая проблемы по пути, так что теперь он загружается, и я могу нажимать по элементам, и никакие диагнозы не производятся до ... Когда я нажимаю кнопка, которая изменяет элементы дерева, сходит с ума и выбрасывает сотни ошибок. Вот небольшое подмножество ошибок:
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=IsIncluded; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=IsIncluded; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 41 : BindingExpression path error: 'IsFolder' property not found for 'object' because data item is null. This could happen because the data provider has not produced any data yet. BindingExpression:Path=IsFolder; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 20 :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=IsFolder; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=IsFolder; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.ResourceDictionary Warning: 9 : Resource not found; ResourceKey='Img_QA'
System.Windows.Data Information: 41 : BindingExpression path error: 'IsIncluded' property not found for 'object' because data item is null. This could happen because the data provider has not produced any data yet. BindingExpression:Path=IsIncluded; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=IsFolder; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
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=IsFolder; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=IsFolder; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 41 : BindingExpression path error: 'IsIncluded' property not found for 'object' because data item is null. This could happen because the data provider has noSystem.Windows.Data Information: 20 : BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=IsIncluded; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
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=IsIncluded; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=IsIncluded; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
t produced any data yet. BindingExpression:Path=IsIncluded; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 20 : BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=IsIncluded; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
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=IsIncluded; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=IsIncluded; DataItem=null; target element is 'TreeViewItemIcon' (Name=''); target property is 'NoTarSystem.Windows.ResourceDictionary Warning: 9 : Resource not found; ResourceKey='Img_QA'
System.Windows.Data Information: 41 : BindingExpression path error: 'Name' property not found for 'object' because data item is null. This could happen because the data provider has not produced any data yet. BindingExpression:Path=Name; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
System.Windows.Data Information: 20 : BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=Name; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
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=Name; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=Name; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
get' (type 'Object')
Если я изменю обработчик кнопки, чтобы просто установить ItemsSource в пустой список, он генерирует тот же огромный набор ошибок. Похоже, что когда источник отключен, WPF переоценивает все привязки и, как и следовало ожидать, все они терпят неудачу.
редактировать
Проще говоря ...
ItemsSource привязан к ObservableCollection.Я вызываю Clear () для ObservableCollection.Все привязки переоценены и могутбольше не могу найти их данные (потому что этобыли удалены)В конечном итоге все предметы удаленыПочему эти привязки переоцениваются? Есть ли способ заставить его убирать предметы без всякой дополнительной работы?
редактировать
Я создал проект, который демонстрирует часть проблемы. Он генерирует ошибки, жалуясь, что ресурсы могутне может быть найдено при вызове Clear (), но это неt генерирует сообщения dataItem = null. Я'Я буду продолжать пытаться воспроизвести те, на простом примере. К сожалению, Я'm заблокирован из pastebin и тому подобное брандмауэром, так что вот код, который изменен из стандартного приложения WPF ...
App.xaml:
MainWindow.xaml:
MainWindow.cs:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ObservableCollectionTest
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
public MainWindow()
{
PresentationTraceSources.DataBindingSource.Listeners.Add(
new ConsoleTraceListener());
PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.All;
InitializeComponent();
}
private void EmptyTheList_Click(object sender, RoutedEventArgs e)
{
(Resources["TheModel"] as Model).Items.Clear();
}
}
}
Model.cs:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
namespace ObservableCollectionTest
{
class Model
{
public ObservableCollection Items { get; set; }
public Model()
{
Items = new ObservableCollection()
{
new TestItem()
{
Name = "TopLevel",
Items = new List()
{
new TestItem() { Name = "Item1", Items = new List() },
new TestItem()
{
Name = "Item2",
Items = new List()
{
new TestItem() { Name = "SubItem1", Items = new List() },
new TestItem() { Name = "SubItem2", Items = new List() },
new TestItem() { Name = "SubItem3", Items = new List() }
}
},
new TestItem() { Name = "Item3", Items = new List() },
new TestItem() { Name = "Item4", Items = new List() }
}
}
};
}
}
class TestItem
{
public string Name { get; set; }
public bool IsRoot { get { return Name == "TopLevel"; } }
public List Items { get; set; }
}
}
Theme.xaml:
Common.xaml:
FWIW, яЯ также использую .NET 3.5 (я, к сожалению, должен), но эта проблема появилась и в .NET 4.0.
У меня также есть два изображения в проекте:
(VS11_Light_Folder_Closed_In.png) (VS11_Light_Folder_Open_In.png)
редактировать
Пытался поменятьObjectDataProvider
использовать DynamicResource:
Но это породило это исключение: