列表框与网格作为ItemsPanelTemplate产生奇怪的绑定错误 [英] ListBox with Grid as ItemsPanelTemplate produces weird binding errors

查看:247
本文介绍了列表框与网格作为ItemsPanelTemplate产生奇怪的绑定错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个列表框控件,我presenting以网格布局ListBoxItem的对象固定数量。所以,我把我的ItemsPanelTemplate是一个网格。

I've got a ListBox control and I'm presenting a fixed number of ListBoxItem objects in a grid layout. So I've set my ItemsPanelTemplate to be a Grid.

我在访问来自code网格背后配置RowDefinitions和ColumnDefinitions。

I'm accessing the Grid from code behind to configure the RowDefinitions and ColumnDefinitions.

到目前为止,一切都如我所料工作。我有一些自定义的IValueConverter的实现返回Grid.Row和Grid.Column每一个ListBoxItem应该出现在

So far it's all working as I expect. I've got some custom IValueConverter implementations for returning the Grid.Row and Grid.Column that each ListBoxItem should appear in.

不过,我得到奇怪的具有约束力的错误有时,我不能弄清楚到底他们为什么发生,或者即使他们是在我的code。

However I get weird binding errors sometimes, and I can't figure out exactly why they're happening, or even if they're in my code.

下面是我得到的错误:

System.Windows.Data错误:4:找不到源与参考'的RelativeSource FindAncestor,AncestorType ='System.Windows.Controls.ItemsControl',AncestorLevel ='1'的结合。 BindingEx pression:路径= Horizo​​ntalContentAlignment; DataItem的= NULL;目标元素是'ListBoxItem的'(名称=''); target属性是'Horizo​​ntalContentAlignment(类型'的Horizo​​ntalAlignment')

任何人能解释这是怎么回事?

Can anybody explain what's going on?

呵呵,而且,这里是我的XAML:

Oh, and, here's my 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>

推荐答案

绑定问题来自于对ListBoxItem的默认样式。默认情况下将样式应用于元素时,WPF查找默认样式并应用没有特别从默认样式的自定义样式设置每个属性。参阅这个伟大的博客文章通过伊恩·格里菲思有关此问题的更多细节。

The binding problem comes from the default style for ListBoxItem. By default when applying styles to elements WPF looks for the default styles and applies each property that is not specifically set in the custom style from the default style. Refer to this great blog post By Ian Griffiths for more details on this behavior.

回到我们的问题。下面是ListBoxItem的默认样式:

Back to our problem. Here is the default style for ListBoxItem:

<Style
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:s="clr-namespace:System;assembly=mscorlib"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    TargetType="{x:Type ListBoxItem}">
    <Style.Resources>
       <ResourceDictionary/>
    </Style.Resources>
    <Setter Property="Panel.Background">
       <Setter.Value>
          <SolidColorBrush>
        #00FFFFFF
          </SolidColorBrush>
       </Setter.Value>
    </Setter>
    <Setter Property="Control.HorizontalContentAlignment">
       <Setter.Value>
          <Binding Path="HorizontalContentAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}"/>
       </Setter.Value>
    </Setter>
    <Setter Property="Control.VerticalContentAlignment">
       <Setter.Value>
          <Binding Path="VerticalContentAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}"/>
       </Setter.Value>
    </Setter>
    <Setter Property="Control.Padding">
       <Setter.Value>
          <Thickness>
        2,0,0,0
          </Thickness>
       </Setter.Value>
    </Setter>
    <Setter Property="Control.Template">
       <Setter.Value>
          <ControlTemplate TargetType="{x:Type ListBoxItem}">
             ...
          </ControlTemplate>
       </Setter.Value>
    </Setter>
 </Style>

请注意,我已经删除了的ControlTemplate使其紧凑(我已经使用的 StyleSnooper 检索样式)。你可以看到,有一个与设置为祖先类型的ItemsControl相对源绑定。因此,在你的情况被结合时,并没有发现他们的ItemsControl创建的ListBoxItems。你能提供什么的ItemsSource为您的列表框的详细信息?

Note that I have removed the ControlTemplate to make it compact (I have used StyleSnooper to retrieve the style). You can see that there is a binding with a relative source set to ancestor with type ItemsControl. So in your case the ListBoxItems that are created when binding did not find their ItemsControl. Can you provide more info with what is the ItemsSource for your ListBox?

PS:删除错误的一种方法是在你的自定义样式创建Horizo​​ntalContentAlignment和VerticalContentAlignment新制定者

P.S.: One way to remove the errors is to create new setters for HorizontalContentAlignment and VerticalContentAlignment in your custom Style.

这篇关于列表框与网格作为ItemsPanelTemplate产生奇怪的绑定错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆