Почему 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>.