在 ListBox 中根据 ListBoxItem 的索引样式化 ListBoxItem。

3
如果SomeProperty的值为10,我想要在没有代码后台的情况下更改ListBox中第一项的边距。以下是我目前的内容:
<ListBox  x:Class="Windows.CustomList"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:Windows"
                 mc:Ignorable="d" x:Name="MyList"
                 d:DesignHeight="300" d:DesignWidth="300">
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=SomeProperty}" Value="10"/>
                        <Condition Binding="{Binding Path=Items.Count, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}}" Value="1" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="Margin">
                        <Setter.Value>
                            <Thickness Left="500"/>
                        </Setter.Value>
                    </Setter>
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <local:ListBoxItemCustomTemplate/>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

当我尝试这种方法时,会出现以下错误:

System.Windows.Data Error: 4 : 找不到'相对源查找祖先,祖先类型='ListBox',祖先级别='1''的绑定源。 BindingExpression:Path=Items.Count; DataItem=null; target element is 'ListBox' (Name=''); target property is 'NoTarget' (type 'Object')

如果只有第一个条件,则可以正确应用边距。 另一种尝试的方法是使用ElementName:

这种方法没有报错,但也没有起作用。
如有任何帮助,将不胜感激。

你能为CustomList添加代码吗? - kmatyaszek
如果 ListBox 中只有一个项目,那么这将仅为第一个项目 ID 设置样式... - H.B.
此外,绑定错误是意外的,尽管逻辑上应该可以工作。 - H.B.
@H.B. 如果列表中只有一个项目,则仅对第一个项目进行样式设置是可以的。但我遇到的问题是错误提示,我的猜测是它找不到父级,因为它是ItemContainerStyle的一部分;顺便说一下,我认为这不应该有影响。 - Aris
@Aris:我甚至无法重现那个错误,对我来说绑定按预期工作。 - H.B.
2个回答

5
请参见AlternationIndex。(您可以使用非常高的AlternationCount来确保只有第一个项目具有索引0并在其上触发)。
这种方法有点滥用,更清晰的方法是使用值转换器/多值转换器,通过类似于listBox.Items.IndexOf(currentItem)的方式获取索引。

3
可以将AlternationCount绑定到项的数量上,而不是使用任意高的AlternationCount,这样每个项的AlternationIndex就是唯一的。AlternationCount="{Binding Items.Count, RelativeSource={RelativeSource Self}}" - Craig

0
另一个解决方案是子类化列表框,并覆盖PrepareContainerForItemOverride方法。请参见下面的示例(它适用于WP7中的Silverlight,因此我没有AlternationIndex)...
public class ListBoxEx: ListBox
{
    public interface iContainerStyle
    {
        Thickness containerMargin { get; }
        Thickness containerPadding { get; }
    };

    protected override void PrepareContainerForItemOverride( DependencyObject element, Object item )
    {
        base.PrepareContainerForItemOverride( element, item );

        var style = item as iContainerStyle;
        if( null == style )
            return;

        var container = element as ListBoxItem;
        if( null == container )
            return;
        container.Margin = style.containerMargin;
        container.Padding = style.containerPadding;
    }
}

然后我从ListBoxEx.iContainerStyle派生我的项目,以获得不同项目的不同边距。


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