ListBox, DataTemplate и триггеры - PullRequest
       0

ListBox, DataTemplate и триггеры

1 голос
/ 05 ноября 2011

Я получил DataTemplate для listboxitem, и я хочу создать триггер, поэтому, когда пользователь щелкает элемент, фон изменится, а также метка

мой код:

<Window.Resources>
    <Style x:Key="RoundedItem" TargetType="ListBoxItem">
        <EventSetter Event="MouseDoubleClick" Handler="listViewItem_MouseDoubleClick" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border Name="ItemBorder" CornerRadius="10" BorderBrush="Black" BorderThickness="1" Margin="1" Background="Transparent">
                        <Label Name="ItemLabel" Foreground="Red" >
                            <ContentPresenter />
                        </Label>
                    </Border>

                        <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter TargetName="ItemBorder" Property="Background" Value="DeepSkyBlue" />
                            <Setter TargetName="ItemLabel" Property="Foreground" Value="Orange" />
                        </Trigger>

                    </ControlTemplate.Triggers>
                </ControlTemplate>

            </Setter.Value>
        </Setter>
    </Style>

    <DataTemplate x:Key="TitleTemplate" DataType="models:Title" >
        <StackPanel>
                <Image Source="{Binding ThumbFilePath}" Width="50" HorizontalAlignment="Center"/>
            <Label Content="{Binding Name}" HorizontalAlignment="Center" />
            <TextBlock Text="{Binding Description}" HorizontalAlignment="Center"  TextWrapping="Wrap" Padding="5,5,5,5"/>
        </StackPanel>
    </DataTemplate>

</Window.Resources>

Что случилось, так это то, что TextBlock изменил свой цвет, а не метку.

кто-нибудь знает почему? Благодаря.

Ответы [ 2 ]

4 голосов
/ 07 ноября 2011

TextBlock наследует определение переднего плана от своих родителей в визуальном дереве.Label, с другой стороны, определяет передний план в его стиле по умолчанию.

Ваш подход "не-WPF-подобен" - вы не должны заключать ContentPresenter в элемент управления Label.

Правильный подход зависит от того, хотите ли вы весь текст в элементе, чтобы изменить его передний план, или просто метку?

[В обоих случаяхНет очевидного преимущества использования Label в шаблоне данных - поэтому я предполагаю, что метка будет изменена на TextBlock.]

Если ответ на поставленный выше вопрос состоит в том, что всетекст должен быть изменен: в ControlTemplate из ListBoxItem, в триггере для IsSelected, из секундного установщика удалите TargetName="ItemLabel", так что последний установщик:

<Setter Property="Foreground" Value="Orange" />

Это изменит передний планэлемента, который повлияет на передний план обоих TextBlock s в шаблоне данных.

Если вы хотите повлиять только на один из текстовых блоков:

1. remove the setter for the foreground from the control template
2. add a trigger to your data template:

<DataTemplate>
    <StackPanel>
        <Image .../>
        <TextBlock x:Name="Text01" ..../>
        <TextBlock x:Name="Text02" ..../>
    </StackPanel>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True">
            <Setter TargetName="Text01" Property="Foreground" Value="Orange"/>
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

Примечание: если вы имеет , чтобы использовать Label элемент управления в шаблоне данных, привязать его свойство Foregroundна передний план элемента списка, например, так:

<Label Foreground="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"....../>

Если это не помогает, это означает, что ваш элемент списка наследует свой передний план, поэтому используйте:

<Label Foreground="{Binding TextElement.Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"....../>
1 голос
/ 06 ноября 2014

Я хочу обратить внимание на то, что у меня возникла похожая проблема, когда я добавил ListBox.ItemTemplate в свой ListBox, и стиль больше не применялся к тексту.

Что яя пытался отобразить список языков (CultureInfo), из которых пользователь мог выбирать, однако я хотел, чтобы отображались нативные имена, а не английское имя.По какой-то причине не все языки имеют свои родные имена с заглавной буквы в их CultureInfo, и NativeName является единственным экземпляром их имени, поэтому мне нужно было применить функцию к CultureInfo.NativeName, чтобы самим использовать заглавные буквы.Для этого я добавил ItemTemplate с шаблоном данных внутри, к которому применил конвертер.

<ListBox IsSynchronizedWithCurrentItem="True" VerticalAlignment="Center" MinHeight="200" x:Name="cbLanguages" 
    ItemsSource="{Binding Path=SupportedCultures, Mode=OneWay, Source={StaticResource CultureResourcesDS}}"
    FontSize="24" HorizontalAlignment="Stretch" Width="300" Margin="10"
    Style="{DynamicResource ListBoxTemplate}" ItemContainerStyle="{DynamicResource ListBoxItemStyle}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Label Content="{Binding Converter={StaticResource NativeNameConverter}}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Через некоторое время поиска я наткнулся на ответ XAMeLi здесь, и изменил меткуЯ бы поместил DataTemplate в TextBox, и созданный мною ListBoxItemStyle снова заработал.

По сути, Labels и TextBoxes имеют разные черты, которые могут использоваться или могут вызывать раздражающие проблемыдело.Вот хорошее объяснение с некоторыми примерами различий: http://joshsmithonwpf.wordpress.com/2007/07/04/differences-between-label-and-textblock/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...