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

发布于 2024-07-06 04:30:00 字数 4306 浏览 11 评论 0原文

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

我从后面的代码访问网格以配置 RowDefinitions 和 ColumnDefinitions。

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

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

这是我得到的错误:

System.Windows.Data 错误:4:无法找到与引用“RelativeSource FindAncestor、AncestorType='System.Windows.Controls.ItemsControl”、AncestorLevel='1'' 进行绑定的源。 BindingExpression:Path=Horizo​​ntalContentAlignment; 数据项=空; 目标元素是“ListBoxItem”(名称=“”); 目标属性是“Horizo​​ntalContentAlignment”(类型“Horizo​​ntalAlignment”)

任何人都可以解释发生了什么吗?

哦,还有,这是我的 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>

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.

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

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.

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.

Here's the error I get:

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')

Can anybody explain what's going on?

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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

怎樣才叫好 2024-07-13 04:30:00

根据 MSDN 上的数据模板概述DataTemplates< /code> 应该用作 ItemTemplate 来定义数据的呈现方式,而 Style 将用作 ItemContainerStyle 来设置样式生成的容器,例如ListBoxItem

但是,您似乎正在尝试使用后者来完成前者的工作。 如果没有更多代码,我无法重新创建您的情况,但我怀疑以容器样式进行数据绑定可能会破坏假定的视觉/逻辑树。

我也忍不住认为基于项目信息的自定义项目布局需要创建自定义Panel。 使用自定义 Panel 来布局项目可能比使用 Rube Goldberg 分类的 IValueConverters 来布局项目更好。

According to the Data Templating Overview on MSDN, DataTemplates should be used as the ItemTemplate to define how the data is presented, while a Style would be used as the ItemContainerStyle to style just the generated container, such as ListBoxItem.

However, it appears that you are trying to use the latter to do the job of the former. I can't recreate your situation without much more code, but I suspect that doing databinding in the container style could be throwing a wrench in the assumed visual/logical tree.

I also can't help but think that a custom layout of items based on the item's information calls for creating a custom Panel. It's probably better for the custom Panel to layout the items than for the items to lay themselves out with a Rube Goldberg assortment of IValueConverters.

瑶笙 2024-07-13 04:30:00

对我有用的另一个解决方法/解决方案是通过在类或顶级窗口的构造函数中将数据绑定源开关级别设置为关键来抑制这些错误(实际上,将它们称为警告似乎更合适) -

#if DEBUG     
    System.Diagnostics.PresentationTraceSources.DataBindingSource.Switch.Level =
        System.Diagnostics.SourceLevels.Critical;
#endif

参考:< a href="http://www.codeproject.com/Tips/124556/How-to-suppress-the-System-Windows-Data-Error-warn" rel="nofollow noreferrer">如何抑制 System.Windows .数据错误警告消息

Another workaround/solution that worked for me was to suppress these errors (actually, it seems more appropriate to call them warnings) by setting the data binding source switch level as critical in constructor of the class or a top level window -

#if DEBUG     
    System.Diagnostics.PresentationTraceSources.DataBindingSource.Switch.Level =
        System.Diagnostics.SourceLevels.Critical;
#endif

Ref.: How to suppress the System.Windows.Data Error warning message

π浅易 2024-07-13 04:30:00

绑定问题来自于ListBoxItem的默认样式。 默认情况下,当将样式应用于元素时,WPF 会查找默认样式并应用默认样式中未在自定义样式中专门设置的每个属性。 请参阅 Ian Griffiths 撰写的这篇精彩的博客文章了解更多信息有关此行为的详细信息。

回到我们的问题。 这是 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< /a> - 检索样式)。 您可以看到有一个绑定,其相对源设置为 ItemsControl 类型的祖先。 因此,在您的情况下,绑定时创建的 ListBoxItems 找不到其 ItemsControl。 您能否提供有关列表框的 ItemsSource 的更多信息?

PS:消除错误的一种方法是在自定义样式中为 Horizo​​ntalContentAlignment 和 VerticalContentAlignment 创建新的设置器。

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.

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>

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?

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

别闹i 2024-07-13 04:30:00

ItemContainerStyle 中将 OverridesDefaultStyle 设置为 True 也可以解决这些问题。

<Style TargetType="ListBoxItem">
    <Setter Property="OverridesDefaultStyle" Value="True"/>
    <!-- set the rest of your setters, including Template, here -->
</Style>

Setting OverridesDefaultStyle to True in your ItemContainerStyle will also fix these problems.

<Style TargetType="ListBoxItem">
    <Setter Property="OverridesDefaultStyle" Value="True"/>
    <!-- set the rest of your setters, including Template, here -->
</Style>
离去的眼神 2024-07-13 04:30:00

这是 ListBoxItem 的常见问题 code> 和其他临时 *Item 容器。 它们是在加载/渲染 ItemsControl 时异步/动态创建的。 您必须附加到 ListBox。 ItemContainerGeneratorStatusChanged 事件并等待 Status 变为 ItemsGenerated,然后再尝试访问它们。

This is a common problem with ListBoxItems and other ephemeral *Item containers. They are created asynchronously/on the fly, while the ItemsControl is loaded/rendered. You have to attach to ListBox.ItemContainerGenerator's StatusChanged event and wait for the Status to become ItemsGenerated before trying to access them.

月亮是我掰弯的 2024-07-13 04:30:00

这是这里其他答案的混合体,但对我来说,我必须在两个地方应用 Setter 来解决错误,尽管这是在使用自定义 VirtualizingWrapPanel

如果我删除以下任一 Setter 声明,我的错误就会再次出现。

        <ListView>
            <ListView.Resources>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Left" />
                    <Setter Property="VerticalContentAlignment" Value="Top" />
                </Style>
            </ListView.Resources>
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Left" />
                    <Setter Property="VerticalContentAlignment" Value="Top" />
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <controls:VirtualizingWrapPanel />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
        </ListView>

我目前确实没有时间进一步调查,但我怀疑这与 JTango 在他的答案中提到的默认样式有关 - 我并没有真正在很大程度上自定义我的模板。

我认为其他答案有更多的意义,但我想我会发布这个,以防它对有同样想法的人有帮助。

大卫·施密特的回答看起来可能描述了根本原因。

This is an amalgam of the other answers here, but for me, I had to apply the Setter in two places to solve the error, although this was when using a custom VirtualizingWrapPanel

If I remove either one of the below Setter declarations, my errors reappear.

        <ListView>
            <ListView.Resources>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Left" />
                    <Setter Property="VerticalContentAlignment" Value="Top" />
                </Style>
            </ListView.Resources>
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Left" />
                    <Setter Property="VerticalContentAlignment" Value="Top" />
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <controls:VirtualizingWrapPanel />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
        </ListView>

I don't really have the time to investigate further at the moment, but I suspect it's related to the default style that JTango mentions in his answer - I'm not really customising my template to a huge degree.

I think there's more mileage to be had out of the other answers, but I thought I'd post this on the off chance it helps someone in the same boat.

David Schmitt's answer looks like it might describe the root cause.

墟烟 2024-07-13 04:30:00

我刚刚遇到了同样类型的错误:

System.Windows.Data 错误:4:
找不到参考绑定的来源
'RelativeSource FindAncestor,AncestorType='System.Windows.Controls.ItemsControl',AncestorLevel='1''。
BindingExpression:Path=Horizo​​ntalContentAlignment;
数据项=空; 目标元素是“ListBoxItem”(名称=“”);
目标属性是“Horizo​​ntalContentAlignment”(类型“Horizo​​ntalAlignment”)

在进行如下绑定时发生这种情况:

<ListBox ItemsSource="{Binding Path=MyListProperty}"  />

对于我的数据上下文对象上的此属性:

public IList<ListBoxItem> MyListProperty{ get; set;}

经过一些实验,我发现仅当项目数量超过可见高度时才会触发错误我的列表框(例如,当出现垂直滚动条时)。
所以我立即想到了虚拟化并尝试了这个:

<ListBox ItemsSource="{Binding Path=MyListProperty}" VirtualizingStackPanel.IsVirtualizing="False" />

这为我解决了问题。
尽管我更愿意保持虚拟化处于开启状态,但我没有再花时间去深入研究它。
我的应用程序有点复杂,有多层网格、停靠面板等以及一些异步方法调用。
我无法在更简单的应用程序中重现该问题。

I just encountered the same type of error:

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')

This happened while doing a binding like this:

<ListBox ItemsSource="{Binding Path=MyListProperty}"  />

To this property on my data context object:

public IList<ListBoxItem> MyListProperty{ get; set;}

After some experimenting I discovered that the error was only triggered when the number of items exceeded the visible height of my ListBox (e.g. when vertical scrollbars appear).
So I immediately thought about virtualization and tried this:

<ListBox ItemsSource="{Binding Path=MyListProperty}" VirtualizingStackPanel.IsVirtualizing="False" />

This solved the problem for me.
Although I would prefer to keep virtualization turned on I did not use any more time to dive into it.
My application is a bit on the complex side with mulitiple levels of grids, dock panels etc. and some asynch method calls.
I was not able to reproduce the problem in a simpler application.

一口甜 2024-07-13 04:30:00

这对我有用。 将其放入您的 Application.xaml 文件中。

<Application.Resources>
    <Style TargetType="ListBoxItem">
        <Setter Property="HorizontalContentAlignment" Value="Left" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
    </Style>
</Application.Resources>

来自...

http://social.msdn.microsoft .com/Forums/en-US/wpf/thread/42cd1554-de7a

This worked for me. Put this in your Application.xaml file.

<Application.Resources>
    <Style TargetType="ListBoxItem">
        <Setter Property="HorizontalContentAlignment" Value="Left" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
    </Style>
</Application.Resources>

from...

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/42cd1554-de7a

哥,最终变帅啦 2024-07-13 04:30:00

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

所以我的代码:

<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 不存在时,不会出现此错误。

I had the same problem as you and I just wanted to share what was my solution.
I have tried all options from this post but the last one was the best for me - thx Chris.

So my code:

<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>

I have also discovered that this bug do not appear when custom ItemsPanelTemplate do not exists.

看轻我的陪伴 2024-07-13 04:30:00

如果您想完全替换 ListBoxItem 模板,以便没有任何选择可见(也许您希望 ItemsControl 的外观具有 ListBox 的分组/等行为code>) 那么您可以使用此样式:

<Style TargetType="ListBoxItem">
  <Setter Property="Margin" Value="2" />
  <Setter Property="FocusVisualStyle" Value="{x:Null}" />
  <Setter Property="OverridesDefaultStyle" Value="True" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type ListBoxItem}">
        <ContentPresenter Content="{TemplateBinding ContentControl.Content}" 
                          HorizontalAlignment="Stretch" 
                          VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" 
                          SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

此模板还排除了标准 Border 包装器。 如果需要,可以使用以下内容替换模板:

<Border BorderThickness="{TemplateBinding Border.BorderThickness}" 
        Padding="{TemplateBinding Control.Padding}" 
        BorderBrush="{TemplateBinding Border.BorderBrush}" 
        Background="{TemplateBinding Panel.Background}" 
        SnapsToDevicePixels="True">
  <ContentPresenter Content="{TemplateBinding ContentControl.Content}" 
                    ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" 
                    HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" 
                    VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" 
                    SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>

如果不需要所有这些 TemplateBinding 值,则可以删除一些值以提高性能。

If you want to completely replace the ListBoxItem template such that no selection is visible (perhaps you want the look of ItemsControl with the grouping/etc behaviour of ListBox) then you can use this style:

<Style TargetType="ListBoxItem">
  <Setter Property="Margin" Value="2" />
  <Setter Property="FocusVisualStyle" Value="{x:Null}" />
  <Setter Property="OverridesDefaultStyle" Value="True" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type ListBoxItem}">
        <ContentPresenter Content="{TemplateBinding ContentControl.Content}" 
                          HorizontalAlignment="Stretch" 
                          VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" 
                          SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

This template also excludes the standard Border wrapper. If you need that, you can use replace the template with this:

<Border BorderThickness="{TemplateBinding Border.BorderThickness}" 
        Padding="{TemplateBinding Control.Padding}" 
        BorderBrush="{TemplateBinding Border.BorderBrush}" 
        Background="{TemplateBinding Panel.Background}" 
        SnapsToDevicePixels="True">
  <ContentPresenter Content="{TemplateBinding ContentControl.Content}" 
                    ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" 
                    HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" 
                    VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" 
                    SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>

If you don't need all these TemplateBinding values then you can remove some for performance.

紫轩蝶泪 2024-07-13 04:30:00

简单地为“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>

Simply creating a default style for the type "ComboBoxItem" doesn't work, because it it overwritten by the ComboBox's default "ItemContainerStyle". To really get rid of this, you need to change the default "ItemContainerStyle" for ComboBoxes, like this:

<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>
≈。彩虹 2024-07-13 04:30:00

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

卡特的建议对我有用。 添加一个没有键的单独“默认”样式和定义 Horizo​​ntalContentAlignment 属性的 TargetType="ListBoxItem" 解决了该问题。 我什至不需要为其设置 OverridesDefaultStyle 属性。

I started running into this problem, even though my ListBox had both a Style and an ItemContainerStyle set - and these named styles had already defined HorizontalContentAlignment. I was using CheckBox controls to turn on/off live filtering on my ListBox and this seemed to be causing the items to pull instead from the default style instead of my assigned styles. Most errors would occur the first time the live filtering kicked in, but thereafter it would continue to throw 2 errors on each change. I find it interesting that exactly 2 records in my collection were empty and thus had nothing to display in the item. So this seems to have contibuted. I plan to create default data to be displayed when a record is empty.

Carter's suggestion worked for me. Adding a separate "default" style with no key and a TargetType="ListBoxItem" that defined the HorizontalContentAlignment property solved the problem. I didn't even need to set the OverridesDefaultStyle property for it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文