2012-07-12 97 views
1

如果SomeProperty值为10,且没有代码隐藏,我想更改ListBox中第一项的边距。 这是我到目前为止有:根据列表框中的索引设置ListBoxItem的样式

<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 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='ListBox', AncestorLevel='1''. BindingExpression:Path=Items.Count; DataItem=null; target element is 'ListBox' (Name=''); target property is 'NoTarget' (type 'Object')

如果我只有第一个条件,正确适用的保证金。 我尝试另一种方法是使用的ElementName:

这种方法不会给任何错误,但它不工作要么。

任何帮助将不胜感激。

+0

你可以添加CustomList的代码吗? – kmatyaszek 2012-07-12 23:53:13

+0

这只会设置第一个项目id的样式,ListBox中只有一个项目... – 2012-07-13 00:00:55

+0

...还有,绑定错误是意外的,虽然逻辑上它应该工作。 – 2012-07-13 00:11:17

回答

3

请参阅AlternationIndex。 (您可以使用非常高的AlternationCount来确保只有第一个项目的索引号为0,并在其上触发)。

这是一个有点滥用,一个更清洁的方法将是价值转换器/多值转换器,通过像listBox.Items.IndexOf(currentItem)这样的索引获得索引。

+3

而不是使用任意高的'AlternationCount',您可以将它绑定到项目的计数,以便AlternationIndex对每个项目都是唯一的。 'AlternationCount =“{Binding Items.Count, RelativeSource = {RelativeSource Self }}“' – Craig 2015-05-01 09:57:46

0

另一种解决方案是子类化列表框,并重写PrepareContainerForItemOverride方法。见我下面的例子(它是Silverlight的WP7中,所以我没有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我的项目以获取不同的项目不同的利润率。

相关问题