.net - 将 Grid 用作 ItemsPanelTemplate 的 ListBox 会产生奇怪的绑定(bind)错误

标签 .net wpf data-binding listbox itemspaneltemplate

我有一个 ListBox 控件,并且在网格布局中呈现固定数量的 ListBoxItem 对象。所以我将我的 ItemsPanelTemplate 设置为网格。

我正在从后面的代码访问 Grid 以配置 RowDefinitions 和 ColumnDefinitions。

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

但是有时我会遇到奇怪的绑定(bind)错误,我无法弄清楚它们发生的确切原因,或者即使它们在我的代码中。

这是我得到的错误:

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>

最佳答案

我和你有同样的问题,我只想分享我的解决方案。
我已经尝试了这篇文章中的所有选项,但最后一个对我来说是最好的——谢谢克里斯。

所以我的代码:

<ListBox.Resources>
    <Style x:Key="listBoxItemStyle" TargetType="ListBoxItem">
        <Setter Property="HorizontalContentAlignment" Value="Center" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="MinWidth" Value="24"/>
        <Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
    </Style>

    <Style TargetType="ListBoxItem" BasedOn="{StaticResource listBoxItemStyle}"/>
</ListBox.Resources>

<ListBox.ItemContainerStyle>
    <Binding Source="{StaticResource listBoxItemStyle}"/>
</ListBox.ItemContainerStyle>

<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <WrapPanel Orientation="Horizontal" IsItemsHost="True" MaxWidth="170"/>
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>

我还发现自定义ItemsPanelTemplate时不会出现这个bug不存在。

关于.net - 将 Grid 用作 ItemsPanelTemplate 的 ListBox 会产生奇怪的绑定(bind)错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/160391/

相关文章:

c# - RabbitMQ EventBasicConsumer 不工作

c# - WP7 - 错误 'XmlException was unhandled' 尽管检查文件是否存在

.net - TCPListener blues,无法弄清楚为什么连接没有正确关闭

c# - 如何正确定义 Model 到 ViewModel 的关系?

c# - 平移 Canvas ,使点 (x,y) 位于中心

c# - 将 WPF 元素本身绑定(bind)到 View 模型对象

android - 数据绑定(bind)中的默认值错误

c# - 将字符串值从 c#.net 传递给 javascript

c# - 从 View 到 ViewModel 的 WPF 事件绑定(bind)?

c# - WPF将 slider 的鼠标位置值绑定(bind)到文本 block