Есть ли способ определить, где привязка 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')

Мой вопрос заключается в том, существует ли способ определить, где эта привязка фактически объявлена ​​(объявлена ​​ли она в XAML или в коде).

Что я пробовал до сих пор:

  • добавлена ​​трассировка отладки для пространства имен System.Windows.Data с установленным уровнем o All; это не дает больше полезной информации
  • попытался выполнить текстовый поиск в проекте для слова Binding в надежде найти все выражения для связывания, для которых Path установлен в HorizontalContentAlignment; Я нашел только один и удалил его, но я все еще получаю сообщение, которое, кажется, указывает, что это не было неисправным..

Знаете ли вы о каких-либо других хитростях, заставляющих WPF выплевывать некоторую полезную информацию о том, где именно объявлена ​​эта привязка?

ОБНОВИТЬ

После нескольких дополнительных поисков я почти уверен, что это вызвано тем, что к MenuItem, Однако я все еще не могу точно определить место, где объявляется ошибочная привязка.

ОБНОВЛЕНИЕ 2

Я нашел проблему. Однако вопрос все еще остается, так как поиск проблемы был главным образом вопросом поиска в темноте на основе ограниченной информации в сообщении об ошибке.

Как оказалось, привязка объявлена ​​в стиле. И стиль не в моем приложении. Это, вероятно, стиль по умолчанию для MenuItem, Так что, чтобы решить проблему, я просто вручную установил HorizontalContentAlignment на все MenuItems, Причина ошибки как-то связана с порядком операций, так как MenuItem генерируется в коде. Я опубликую новый вопрос по этому вопросу отдельно.

Итак, на данный момент, мораль этой истории такова, что я чувствую, что должен быть лучший механизм, чтобы определить, где объявлено ошибочное связывание. Я хотел бы видеть что-то вроде трассировки стека для привязок..

Я оставляю вопрос открытым немного дольше на случай, если кто-нибудь узнает о каких-либо других инструментах или методах определения места, где привязка объявляется в коде или разметке.

Я разместил еще один вопрос относительно стиля / привязки, применяемой к MenuItems здесь

4 ответа

При отладке ошибок привязки WPF проще всего разбить ошибку на точки с запятой и начать с конца

  1. System.Windows.Data Error: 4 :
  2. Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=HorizontalContentAlignment;
  3. DataItem=null;
  4. target element is 'MenuItem' (Name='');
  5. target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')

Итак, начиная с конца:

  • # 5 сообщает, какое свойство содержит привязку, которая не выполняется. В вашем случае это HorizontalContentAlignment

  • #4 является элементом, содержащим свойство с ошибкой, которое является 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.

Может быть, вы могли бы использовать это отличное приложение под названием Snoop. Это бесплатно в CodePlex. Это помогает мне найти несколько проблем связывания и пропустить контексты данных. Это позволяет исследовать все дерево визуалов WPF, а также выдает ошибки привязки.

Надеюсь, что Снуп поможет.

Я новичок в WPF и у меня точно такая же ошибка. Хотя я исправил это сейчас, я действительно не знаю, как... ниже приведены шаги, которые я попробовал:

Прежде всего, у меня есть:

  1. <Menu>
  2. 2 <ContextMenu> определяется в <ListBox.ItemTemplate>

Я пытался:

  1. переместить один <ContextMenu> в <ListBox.ItemContainerStyle> -> ошибка существует
  2. Установить и удалить стиль HorizontalContentAlignment а также VerticalContentAlignment за <Menu>, <ContextMenu>, <MenuItem> -> ошибка существует
  3. Установить Name атрибут для <MenuItem> из <ContextMenu> в <ListBox.ItemTemplate> -> без ошибок!
  4. Удалить Name атрибут -> все еще нет ошибки...
  5. Перезапустите VS -> ошибка, кажется, исчезла навсегда...

В конце концов, у меня есть

  1. <Menu>
  2. <ContextMenu> определяется в <ListBox.ItemTemplate>
  3. <ContextMenu> определяется в <ListBox.ItemContainerStyle>

и никто из них не установил стиль HorizontalContentAlignment а также VerticalContentAlignment, И ошибка ушла...

Кажется, есть некоторые проблемы с обновлением. Таким образом, для тех, у кого такая же проблема, вы можете попробовать перезапустить VS или установить Name атрибут для <MenuItem>...

Ошибка System.Windows.Data: 4 - это не ваша проблема, это проблема, известная WPF. Это связанные комбинированные списки / меню, чьи элементы изменяются динамически. Смотрите это. Кстати, вы можете игнорировать эти ошибки, как правило, приложение работает нормально.

Другие вопросы по тегам