ListBox使用Grid作为ItemsPanelTemplate会产生奇怪的绑定错误

37

我有一个ListBox控件,以网格布局呈现一定数量的ListBoxItem对象。因此,我将ItemsPanelTemplate设置为Grid。

我从代码后台访问Grid以配置RowDefinitions和ColumnDefinitions。

到目前为止,一切都按照预期工作。我有一些自定义的IValueConverter实现,用于返回每个ListBoxItem应该出现在其中的Grid.Row和Grid.Column。

但是,有时候我会遇到奇怪的绑定错误,我无法确定它们为什么发生,甚至无法确定它们是否在我的代码中。

这是我得到的错误:

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=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')

有人能解释一下发生了什么吗?

哦,这是我的XAML:

<UserControl.Resources>
    <!-- Value Converters -->
    <v:GridRowConverter x:Key="GridRowConverter" />
    <v:GridColumnConverter x:Key="GridColumnConverter" />
    <v:DevicePositionConverter x:Key="DevicePositionConverter" />
    <v:DeviceBackgroundConverter x:Key="DeviceBackgroundConverter" />

    <Style x:Key="DeviceContainerStyle" TargetType="{x:Type ListBoxItem}">
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
        <Setter Property="Background" Value="Transparent" />

        <Setter Property="Grid.Row" Value="{Binding Path=DeviceId, Converter={StaticResource GridRowConverter}}" />
        <Setter Property="Grid.Column" Value="{Binding Path=DeviceId, Converter={StaticResource GridColumnConverter}}" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border CornerRadius="2" BorderThickness="1" BorderBrush="White" Margin="2" Name="Bd"
                            Background="{Binding Converter={StaticResource DeviceBackgroundConverter}}">
                        <TextBlock FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center" 
                                Text="{Binding Path=DeviceId, Converter={StaticResource DevicePositionConverter}}" >
                            <TextBlock.LayoutTransform>
                                <RotateTransform Angle="270" />
                            </TextBlock.LayoutTransform>
                        </TextBlock>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter TargetName="Bd" Property="BorderThickness" Value="2" />
                            <Setter TargetName="Bd" Property="Margin" Value="1" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>            
    </Style>        
</UserControl.Resources>

<Border CornerRadius="3" BorderThickness="3" Background="#FF333333" BorderBrush="#FF333333" >
    <Grid ShowGridLines="False">
        <Grid.RowDefinitions>
            <RowDefinition Height="15" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <StackPanel Grid.Row="0" Orientation="Horizontal">
            <Image Margin="20,3,3,3" Source="Barcode.GIF" Width="60" Stretch="Fill" />
        </StackPanel>

        <ListBox ItemsSource="{Binding}" x:Name="lstDevices" Grid.Row="1" 
                 ItemContainerStyle="{StaticResource DeviceContainerStyle}"
                 Background="#FF333333"
                 SelectedItem="{Binding SelectedDeviceResult, ElementName=root, Mode=TwoWay}" >
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <Grid>
                        <Grid.LayoutTransform>
                            <RotateTransform Angle="90" />
                        </Grid.LayoutTransform>                            
                    </Grid>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>
    </Grid>
</Border>


当我在运行时筛选列表时,我遇到了同样的错误。 - Ingó Vals
12个回答

0

仅仅为类型“ComboBoxItem”创建一个默认样式是不起作用的,因为它会被ComboBox的默认“ItemContainerStyle”覆盖。要真正摆脱这个问题,您需要更改ComboBox的默认“ItemContainerStyle”,像这样:

<Style TargetType="ComboBox">
    <Setter Property="ItemContainerStyle">
        <Setter.Value>                
            <Style TargetType="ComboBoxItem">
                <Setter Property="HorizontalContentAlignment" Value="Left" />
                <Setter Property="VerticalContentAlignment" Value="Center" />
            </Style>
        </Setter.Value>
    </Setter>
</Style>

0

我遇到了这个问题,即使我的ListBox已经设置了Style和ItemContainerStyle - 这些命名样式已经定义了HorizontalContentAlignment。我正在使用CheckBox控件来打开/关闭我的ListBox上的实时过滤,这似乎导致项目从默认样式而不是我的分配样式中拉取。大多数错误会在实时过滤第一次启动时发生,但此后每次更改都会继续抛出2个错误。我发现有趣的是,我的集合中恰好有2条记录为空,因此没有任何内容可以显示在该项中。所以这似乎有所贡献。我计划创建默认数据以在记录为空时显示。

Carter的建议对我有用。添加一个单独的“默认”样式,没有键和TargetType =“ListBoxItem”,定义了HorizontalContentAlignment属性解决了问题。我甚至不需要为它设置OverridesDefaultStyle属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接