Контекстно-зависимая привязка данных в WPF - PullRequest
1 голос
/ 11 мая 2011

Очень удобно назначить ListBox.ItemsSource коллекцию, а затем настроить ListBox.ItemTemplate, чтобы дата выглядела так, как я хочу.

Рассмотрите возможность связывания простого списка отсортированных строк.
Если коллекциядостаточно большие, привлекательные якоря пригодятся.

Вот концепция того, что я хочу:
Wpf Пример привязки данных http://bteffective.com/images/Data_Bindining_Example.png

В основном, я хочу, чтобы первая буквабыть другого стиля, если он не соответствует букве предыдущего элемента.Как я могу обратиться к предыдущему пункту в моем DataTemplate?

Ответы [ 2 ]

2 голосов
/ 11 мая 2011

Скорее всего, вам понадобится разобрать ваш список источников в новый список объектов, которые имеют три свойства: первую букву слова, остальную часть слова и логическое значение, указывающее, является ли эта запись «якорем». Тогда ваш DataTemplate может быть TextBlock для первой буквы, за которым следует TextBlock для остальной части слова. Триггер стиля в логическом значении IsAnchor может затем изменить цвет первой буквы.

0 голосов
/ 14 мая 2011

Другой подход с 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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...