Почему StaticResource не может быть разрешен в этом случае?
У меня есть исключение "Невозможно найти ресурс с именем" mrg ". Имена ресурсов чувствительны к регистру." , когда я пытаюсь сделать следующее:
MainWindow.xaml:
<Window.Resources>
<Thickness Left="0"
Right="1"
Bottom="2"
Top="3"
x:Key="mrg" />
</Window.Resources>
<Grid>
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:UserControl1 />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<string> source = new List<string>()
{
"item1",
"item2",
"item3",
"item4",
"item5",
};
DataContext = source;
}
}
и UserControl1.xaml:
<Grid>
<TextBlock Text="{Binding}" Margin="{StaticResource mrg}" />
</Grid>
В соответствии с msdn article:
Поведение статического ресурса
-
Процесс поиска проверяет запрашиваемый ключ в ресурсном словаре, определяемом элементом, который устанавливает свойство.
-
Затем процесс поиска перемещает логическое дерево вверх, в родительский элемент и его словарь ресурсов. Это продолжается до тех пор, пока не будет достигнут корневой элемент.
-
Затем проверяются ресурсы приложений. Ресурсы приложений - это те ресурсы в словаре ресурсов, которые определены объектом Application для вашего приложения WPF.
Таким образом, ресурс должен был быть найден из-за шага 2. Но, как я вижу в окне Locals
, когда исключено исключение, UserControl1.Parent == null
.
Я запутался в этой проблеме. Способ, которым я могу решить это, - перевести ресурс на уровень приложения.
Мой вопрос: почему найден признак StaticResource?
Ответы
Ответ 1
DataTemplate формирует собственное логическое дерево, которое отключается от логического дерева элемента ItemsControl. Следовательно, поиск путем перемещения логического дерева не найдет ресурс.
Мне не удалось найти ссылку в MSDN, просто в этой статье о CodeProject, где она читает:
Элементы, которые являются частью расширенного шаблона, в дальнейшем как "элементы шаблона", образуют свое собственное логическое дерево, которое отключены от логического дерева объекта, для которого они были создан.
Использование DynamicResource
вместо StaticResource
преодолеет проблему. Однако я не могу точно сказать, почему. Может быть, объяснение можно найти в поведении поведения статического ресурса и в динамических разделах поиска ресурсов в Static и Dynamic Resources, но я не уверен.
Ответ 2
StaticResources должны быть определены перед обращением к ним.
Столкнувшись с неизвестной статической ссылкой на ресурс, анализатор XAML выдает исключение. (Эта проблема может быть решена с использованием динамического ресурса, но она несет дополнительные затраты)
Ответ 3
У меня была аналогичная проблема после очистки кода. Код выглядел и компилировался отлично, но во время выполнения создавал бы "StaticResource not found error".
Изменение StaticResource для DynamicResource действительно сработало. Но это действительно спустилось к App.xaml и порядку, в котором ресурсные словари были добавлены в разделе <ResourceDictionary.MergedDictionaries>
.