ListBoxItem создает ошибку "Ошибка System.Windows.Data Error: 4"
Я создал файл ListBox
:
<ListBox x:Name="RecentItemsListBox" Grid.Row="1" BorderThickness="0" Margin="2,0,0,0" SelectionChanged="RecentItemsListBox_SelectionChanged">
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}"
BasedOn="{StaticResource {x:Type ListBoxItem}}">
<Style.Triggers>
<!--This trigger is needed, because RelativeSource binding can only succeeds if the current ListBoxItem is already connected to its visual parent-->
<Trigger Property="IsVisible" Value="True">
<Setter Property="HorizontalContentAlignment"
Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment"
Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0,2,0,0">
<TextBlock Text="{Binding Number}" />
<StackPanel Orientation="Vertical" Margin="7,0,0,0">
<TextBlock Text="{Binding File}" />
<TextBlock Text="{Binding Dir}" Foreground="DarkGray" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Это приведет к тому, что во время выполнения выйдет строка в OutputWindow из VisualStudio:
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 'ListBoxItem' (Name='');
Может кто-нибудь дать мне подсказку, как я могу это решить?
Обновление
Я добавил свойства в стиль, чтобы попытаться устранить предупреждение/ошибку.
Ответы
Ответ 1
Самый простой способ решить этот вопрос - убедиться, что Listbox имеет ItemContainerStyle. См. Следующий пример:
<ListBox x:Name="RecentItemsListBox" Grid.Row="1" BorderThickness="0" Margin="2,0,0,0" SelectionChanged="RecentItemsListBox_SelectionChanged">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
</ListBox.ItemContainerStyle>
...
</ListBox>
Случается, что ваши объекты создаются, и по умолчанию они ищут родительское свойство, которое не определено. Явное определение проблемы решит эту проблему.
У меня была такая же проблема с использованием TreeView и изменение связанного источника для этих шаблонов вызывало бы эти предупреждения.
Ответ 2
Ответ на этот вопрос разрешил мне эту проблему:
ListBox с сеткой как ItemsPanelTemplate создает странные ошибки привязки
Определение стиля верхнего уровня (в моем App.xaml), нацеленного на проблему типа "исправлено" для меня. Вот стиль, который должен сработать для вас:
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
</Style>
В моем случае я создавал некоторые TreeViewItems, а затем привязывал свой TreeView к созданным элементам. Ошибка привязки произошла, потому что привязка TreeViewItem была разрешена до того, как они были добавлены в TreeView. Правильное решение состояло в том, чтобы не создавать TreeViewItem, а вместо этого создавать класс, содержащий нужные мне данные (Header и Items). Просто передайте мою ситуацию, если есть параллели с вашими собственными.
Ответ 3
Другим обходным решением, которое работало на меня, было подавление этих ошибок (на самом деле, более целесообразно называть их предупреждениями) путем установки уровня переключения источника привязки данных как критического в конструкторе класса или окна верхнего уровня -
#if DEBUG
System.Diagnostics.PresentationTraceSources.DataBindingSource.Switch.Level =
System.Diagnostics.SourceLevels.Critical;
#endif
Ref.: Как подавить сообщение об ошибке System.Windows.Data Error
Обновление: это не лучшее решение, но для вредоносных программ это выглядит хорошо для меня.