programing

선택한 경우 ListBox 항목에 대한 WPF DataTemplate 변경

nasanasas 2020. 9. 9. 08:06
반응형

선택한 경우 ListBox 항목에 대한 WPF DataTemplate 변경


항목이 선택되었는지 여부에 따라 ListBox의 항목에 대한 DataTemplate을 변경해야합니다 (선택하면 다른 / 추가 정보 표시).

문제의 ListBox 항목을 클릭 할 때 (탭을 통해서만) DataTemplate (StackPanel)의 최상위 요소에 GotFocus / LostFocus 이벤트가 표시되지 않고 아이디어가 없습니다.


가장 쉬운 방법은 "ItemTemplate"속성이 아닌 "ItemContainerStyle"에 대한 템플릿을 제공하는 것입니다. 아래 코드에서 2 개의 데이터 템플릿을 만듭니다. 하나는 "선택되지 않은"상태에 대한 것이고 다른 하나는 "선택된"상태에 대한 것입니다. 그런 다음 항목이 포함 된 실제 "ListBoxItem"인 "ItemContainerStyle"에 대한 템플릿을 만듭니다. 기본 "ContentTemplate"을 "Unselected"상태로 설정 한 다음 "IsSelected"속성이 true 일 때 템플릿을 교체하는 트리거를 제공합니다. (참고 : 단순화를 위해 코드 뒤에있는 "ItemsSource"속성을 문자열 목록으로 설정합니다.)

<Window.Resources>

<DataTemplate x:Key="ItemTemplate">
    <TextBlock Text="{Binding}" Foreground="Red" />
</DataTemplate>

<DataTemplate x:Key="SelectedTemplate">
    <TextBlock Text="{Binding}" Foreground="White" />
</DataTemplate>

<Style TargetType="{x:Type ListBoxItem}" x:Key="ContainerStyle">
    <Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}" />
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
        </Trigger>
    </Style.Triggers>
</Style>

</Window.Resources>
<ListBox x:Name="lstItems" ItemContainerStyle="{StaticResource ContainerStyle}" />

항목이 선택되거나 필요하지 않을 때 스타일을 설정하려면 ListBoxItem상위 항목 을 검색하고 <DataTemplate>변경시 스타일 변경을 트리거하면 IsSelected됩니다. 예를 들어 아래 코드는 TextBlock기본 Foreground색상이 green 입니다. 이제 항목이 선택되면 글꼴이 빨간색으로 바뀌고 마우스가 항목 위에 있으면 노란색으로 바뀝니다 . 이렇게하면 약간 변경하려는 모든 상태에 대해 다른 답변에서 제안한대로 별도의 데이터 템플릿을 지정할 필요가 없습니다.

<DataTemplate x:Key="SimpleDataTemplate">
    <TextBlock Text="{Binding}">
        <TextBlock.Style>
            <Style>
                <Setter Property="TextBlock.Foreground" Value="Green"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={
                        RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem }}}"
                                 Value="True">
                        <Setter Property="TextBlock.Foreground" Value="Red"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=IsMouseOver, RelativeSource={
                        RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem }}}"
                                 Value="True">
                        <Setter Property="TextBlock.Foreground" Value="Yellow"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</DataTemplate>

It should also be noted, that the stackpanel isn't focuable, so it's never going to get focus (set Focusable=True if you /really/ want it focused). However, the key to remember in scenarios like this is that the Stackpanel is child of the TreeViewItem, which is the ItemContainer in this case. As Micah suggests, tweaking the itemcontainerstyle is a good approach.

You could probably do it using DataTemplates, and things such as datatriggers which would use the RelativeSouce markup extension to look for the listviewitem

참고URL : https://stackoverflow.com/questions/146269/change-wpf-datatemplate-for-listbox-item-if-selected

반응형