WPF中的上下文相关数据绑定

时间:2011-05-11 15:38:14

标签: wpf xaml data-binding

分配ListBox.ItemsSource一个集合然后调整ListBox.ItemTemplate以使日期看起来非常方便。

考虑绑定一个简单的排序字符串列表 如果收集足够大,那么引人注目的锚点就会派上用场。

这是我想要的概念:
Wpf Example of a databinding http://bteffective.com/images/Data_Bindining_Example.png

基本上我希望第一个字母具有不同的风格,如果它与前一个项目的字母不匹配。如何处理DataTemplate中的上一项?

2 个答案:

答案 0 :(得分:2)

您可能需要将源列表解析为具有三个属性的新对象列表:单词的第一个字母,单词的其余部分以及指示此条目是否为“锚点”的布尔值。然后,您的DataTemplate可以是第一个字母的TextBlock,后面是TextBlock的其余部分。然后,IsAnchor布尔值上的样式触发器可以更改第一个字母的颜色。

答案 1 :(得分:0)

使用MultiBinding的另一种方法:我将集合作为参数传递,查找上一个元素并检查第一个字母是否匹配。

如果基础集合属于ObservableCollection<T>并且发生更改,则此方法更容易。它也较慢,因为显示元素需要查找前一个元素( O(n)),因此,显示 n 元素是 O(n ^ 2) )

在Xaml中:

<ListBox x:Name="lbExample" >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Converter={StaticResource ResourceKey=first}}">
                    <TextBlock.Style>
                        <Style TargetType="{x:Type TextBlock}">
                            <Style.Triggers>
                                <DataTrigger Value="True">
                                    <DataTrigger.Binding>
                                        <MultiBinding Converter="{StaticResource prevComparerConverter}">
                                            <Binding />
                                            <Binding RelativeSource="{RelativeSource AncestorType={x:Type ListBox}}" Path="ItemsSource"/>
                                        </MultiBinding>
                                    </DataTrigger.Binding>
                                    <Setter Property="Foreground" Value="Red" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </TextBlock.Style>
                </TextBlock>
                <TextBlock Text="{Binding Converter={StaticResource ResourceKey=rest}}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

在代码中:

public class PrevComparerConverter : IMultiValueConverter
{
    private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var item = (string)values[0];
        var col = (ObservableCollection<string>)values[1];

        var ind = col.IndexOf(item);
        var res = true;
        if (ind > 0 && item.Length > 0)
        {
            var prev = col[ind - 1];
            if (prev.Length > 0 && char.ToLowerInvariant(prev[0]) == char.ToLowerInvariant(item[0]))
                res = false;
        }
        return res;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}