Ответ 1
При отладке ошибок привязки WPF я считаю, что проще всего разбить ошибку на точки с запятой и начать с конца
-
System.Windows.Data Error: 4 :
-
Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=HorizontalContentAlignment;
-
DataItem=null;
-
target element is 'MenuItem' (Name='');
-
target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')
Итак, начиная с конца:
-
# 5 сообщает вам, какое свойство содержит привязку, которая терпит неудачу. В вашем случае это
HorizontalContentAlignment
-
# 4 - это элемент, содержащий свойство failing, которое является
MenuItem
без свойстваName
, чтобы идентифицировать его с помощьюИтак, у вас есть
<MenuItem HorizontalContentAlignment="{Binding ...}" />
, который вызывает ошибку привязки. -
# 3 - это
DataItem
илиDataContext
, который находится за целевым элементом. Кажется, для вас этоnull
, но это не проблема, так как похоже, что ваша привязка не ссылается на DataContext.Но это означает, что
MenuItem
не является частью вашего обычногоVisualTree
, так как обычноDataContext
наследуется от родительского объекта. -
# 2 содержит фактическую ошибку привязки и информацию о привязке. На самом деле его можно разбить на несколько частей.
-
Cannot find source for binding
-
with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''.
-
BindingExpression:Path=HorizontalContentAlignment;
"Невозможно найти источник" означает, что привязка не может найти объект-источник для привязки, и в вашем случае этот исходный объект должен быть
{RelativeSource AncestorType={x:Type ItemsControl}
(FindAncestor
иAncestorLevel=1
по умолчанию дляRelativeSource
, поэтому я игнорирую их)И последняя часть # 2 показывает
Path
, с которой вы пытаетесь привязать:HorizontalContentAlignment
-
Итак, чтобы все это было вместе, где-то в вашем коде есть <MenuItem>
, который пытается привязать его HorizontalContentAlignment
к ItemsControl.HorizontalContentAlignment
, но привязка не может найти ItemsControl
.
Вы используете привязку RelativeSource FindAncestor
, чтобы найти ItemsControl
, который ищет визуальное дерево, чтобы найти ближайший ItemsControl
, и он не находит его, поэтому не должно быть ItemsControl
выше в Иерархия VisualTree из MenuItem
.
Я часто вижу эту проблему с ContextMenus
, потому что они не являются частью одного и того же VisualTree
как остальной части вашего XAML-кода. (Чтобы ссылаться на объект в главном VisualTree
, к которому привязан ContextMenu
, вы можете использовать свойство PlacementTarget
, например этот пример.
Как только вы поймете ошибку привязки, ее часто легко найти источник в вашем XAML.
В зависимости от размера моего приложения, я обычно делаю одно из следующих действий:
-
Найдите приложение для "целевого элемента" из ошибки привязки (в вашем случае,
MenuItem
) и посмотрите, устанавливает ли какой-либо из них "целевое свойство" (HorizontalContentAlignment
) с привязкой -
Найдите приложение для "целевого свойства" из ошибки привязки (
HorizontalContentAlignment
), чтобы найти связывание, вызывающее эту проблему. -
Найдите приложение для чего-то достаточно уникального из текста привязки, показанного в ошибке привязки. В вашем случае вы можете попробовать выполнить поиск по
{x:Type ItemsControl}
, который будет частью вашей привязкиRelativeSource
, и не должно быть слишком много результатов поиска для такой фразы. -
Используйте сторонний инструмент, например Snoop или WPF Inspector для отслеживания ошибки привязки во время выполнения.
Я только использовал Snoop раньше, но для его использования вам нужно запустить приложение и запустить Snoop против него, чтобы проверить ваше приложение VisualTree во время его работы. Затем вы можете выполнить поиск в VisualTree, введя что-то вроде "MenuItem" в строке поиска, чтобы отфильтровать визуальное дерево для всех
MenuItems
, затем просмотрите их свойства, чтобы узнать, какая из них имеет ошибку привязки (свойствоHorizontalContentAlignment
будет выделено красным цветом из-за ошибки привязки).Следует отметить, что если ваш
MenuItem
находится внутриContextMenu
, вам нужно открыть этоContextMenu
для отображения элементов MenuItems и отображения в Snoop.