programing

WPF ListView 비활성 선택 항목 색상

lastmoon 2023. 4. 22. 10:01
반응형

WPF ListView 비활성 선택 항목 색상

여러 ListView를 연속으로 선택하는 WPF 애플리케이션을 만들고 있습니다(iTunes 브라우저와 유사).문제는 기본 비활성 선택 색상이 너무 밝다는 것입니다.(아래 참조)기본 비활성 선택 색상(너무 밝음)

비활성 목록 보기를 이렇게 표시하도록 이 색상을 변경하려면 어떻게 해야 합니까?(아래 참조)비활성 및 활성 선택 색상은 동일합니다.

솔루션

디폴트 시스템 컬러를 덮어씁니다.Style다음과 같이 합니다.

<Style TargetType="ListViewItem">
    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{x:Static SystemColors.HighlightColor}"/>
    </Style.Resources>
</Style>

변화하는SystemColors.ControlBrushKey나한테는 통하지 않았어, 난 변해야 했어SystemColors.InactiveSelectionHighlightBrushKey

그래서 다음 대신:

<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Red" />

다음을 사용해야 했습니다.

<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="Red"/>

ListBox템플릿은 시스템 색상을 사용합니다.ControlBrush비활성 하이라이트 색상을 설정합니다.따라서 이 색상을 덮어쓸 수 있습니다.

<ListBox>
    <ListBox.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}">Red</SolidColorBrush>
    </ListBox.Resources>
</ListBox>

경우에 따라서는 문제를 해결할 수 있지만, 컨트롤이 비활성화/읽기 전용으로 되어 있으면 문제가 발생하고 색 구성표보다 우선하기 때문에 이상적이지 않습니다.대신 ListBox 태그에 다음 항목을 추가하는 것이 좋습니다.

<ListBox....>
    <ListBox.Resources>
            <Style TargetType="ListBoxItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <Border Name="Border" Padding="2" SnapsToDevicePixels="true">
                                <ContentPresenter />
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsSelected" Value="true">
                                    <Setter TargetName="Border" Property="Background"
                                            Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
        </Style>
    </ListBox.Resources>
</ListBox>

이렇게 하면 목록 상자 항목을 선택할 때마다(컨트롤 상태에 관계없이) 배경색 강조 표시를 설정할 수 있습니다.

제 답변은 이미 답변한 도움말과 다음 블로그를 기반으로 합니다.http://blogs.vbcity.com/xtab/archive/2009/06/29/9344.aspx

SystemColors의 일부 속성을 덮어쓸 필요가 있습니다.SystemColors Class(MSDN)를 확인합니다.Inactive Selection보다 많은 속성이 있습니다.[BrushKey]를 강조 표시합니다(예:비활성 선택텍스트 색상에 영향을 주는 HighlightTextBrushKey.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red"/>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="White"/>
        <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="Yellow"/>
        <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}" Color="Blue"/>
        <Style TargetType="ListViewItem">
            <Setter Property="FontSize" Value="20" />
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="Padding" Value="25,5" />
        </Style>
    </Window.Resources>
    <StackPanel Orientation="Horizontal">
        <ListView>
            <ListViewItem Content="Item" />
            <ListViewItem Content="Item" />
        </ListView>
        <ListView>
            <ListViewItem Content="Item" />
            <ListViewItem Content="Item" />
        </ListView>
    </StackPanel>
</Window>

여기에 이미지 설명 입력

이전 버전에서는.NET Frameworks는 시스템 색상을 덮어쓰지 않습니다.에서 동작하는 솔루션.NET Framework 4.0을 소개합니다.

<ListView>
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListViewItem}">
                <Border x:Name="Bd"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Background="{TemplateBinding Background}"
                        Padding="{TemplateBinding Padding}"
                        SnapsToDevicePixels="true">
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                </Border>
                <ControlTemplate.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Selector.IsSelectionActive"
                                        Value="False" />
                            <Condition Property="IsSelected"
                                        Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter Property="Background"
                                TargetName="Bd"
                                Value="DarkOrange" />
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Selector.IsSelectionActive"
                                        Value="True" />
                            <Condition Property="IsSelected"
                                        Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter Property="Background"
                                TargetName="Bd"
                                Value="OrangeRed" />
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

ListBox 와 ListView 의 양쪽 모두에 대응합니다.

다른 답변을 바탕으로 다음 항목을 사용하여 실제 값을 하드코딩하지 않고 활성화 및 비활성 색상을 동일하게 만들었습니다.

<ListBox.Resources>
    <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" 
                     Color="{x:Static SystemColors.HighlightColor}"/>
    <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}"
                     Color="{x:Static SystemColors.HighlightTextColor}"/>
</ListBox.Resources>

액티브와 비액티브 모두 같은 색상으로 하는 것은 이상적이지 않을 수 있지만 디폴트 색상이 너무 희미해서 비액티브 시에는 어떤 아이템이 선택되었는지 알 수 없기 때문에 확실히 개선되었습니다.

다른 대부분의 답변에서 알 수 있듯이 SystemColors를 덮어쓰는 것은 제게는 효과가 없었습니다.ListBoxItem 기본 스타일을 편집하고 특정 ListBox의 ItemContainerStyle을 편집한 스타일로 설정했습니다.다른 컨트롤에 대한 기본 스타일을 편집하는 것에 비해 비교적 쉬운 작업입니다.항목을 변경하기만 하면 됩니다.선택된활발하지 않은.배경과 항목.선택된활발하지 않은.원하는 색상으로 테두리를 두릅니다.

   <SolidColorBrush x:Key="Item.Static.Background" Color="#FFFCFCFC" />
    <SolidColorBrush x:Key="Item.Static.Border" Color="#FFFCFCFC" />
    <SolidColorBrush x:Key="Item.MouseOver.Background" Color="#1F26A0DA" />
    <SolidColorBrush x:Key="Item.MouseOver.Border" Color="#a826A0Da" />
    <SolidColorBrush x:Key="Item.SelectedActive.Background" Color="#3D26A0DA" />
    <SolidColorBrush x:Key="Item.SelectedActive.Border" Color="#FF26A0DA" />
    <SolidColorBrush x:Key="Item.SelectedInactive.Background" Color="#3DDADADA" />
    <SolidColorBrush x:Key="Item.SelectedInactive.Border" Color="#FFDADADA" />
    <Style x:Key="ModifiedColorListBox" TargetType="{x:Type ListBoxItem}">
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="Padding" Value="4,1" />
        <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="BorderBrush" Value="Transparent" />
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border x:Name="Bd" 
                        BorderBrush="{TemplateBinding BorderBrush}" 
                        BorderThickness="{TemplateBinding BorderThickness}" 
                        Background="{TemplateBinding Background}" 
                        Padding="{TemplateBinding Padding}" 
                        SnapsToDevicePixels="true">
                        <ContentPresenter 
                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    </Border>
                    <ControlTemplate.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsMouseOver" Value="True" />
                            </MultiTrigger.Conditions>
                            <Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.MouseOver.Background}" />
                            <Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.MouseOver.Border}" />
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Selector.IsSelectionActive" Value="False" />
                                <Condition Property="IsSelected" Value="True" />
                            </MultiTrigger.Conditions>
                            <Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.SelectedInactive.Background}" />
                            <Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.SelectedInactive.Border}" />
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Selector.IsSelectionActive" Value="True" />
                                <Condition Property="IsSelected" Value="True" />
                            </MultiTrigger.Conditions>
                            <Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.SelectedActive.Background}" />
                            <Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.SelectedActive.Border}" />
                        </MultiTrigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter TargetName="Bd" Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

그리고 xaml에서 사용하는 방법:

<ListBox
    Name="SomeListBox"
    ItemContainerStyle="{StaticResource ModifiedColorListBox}"
    ItemsSource="{Binding SomeCollection}"
    SelectedItem="{Binding SomeObject}">
</ListBox>

나는 이것이 성공적이었다.

 <ListBox HorizontalContentAlignment="Stretch">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Label  Margin="-5, -2,-5,-2" Content="{Binding Item}">
                            <Label.Style>
                                <Style TargetType="Label">
                                    <Style.Triggers>
                                        <MultiDataTrigger>
                                            <MultiDataTrigger.Conditions>
                                                <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBox}},Path=IsFocused}" Value="False"/>
                                                <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="True"/>
                                            </MultiDataTrigger.Conditions>
                                            <Setter Property="Background" Value="CornflowerBlue"/>
                                        </MultiDataTrigger>
                                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="True">
                                            <Setter Property="Foreground" Value="White"/>
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="False">
                                            <Setter Property="Foreground" Value="Black"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Label.Style>
                        </Label>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

언급URL : https://stackoverflow.com/questions/382006/wpf-listview-inactive-selection-color

반응형