[.net] 선택한 경우 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>


답변

또한 스택 패널은 초점을 맞출 수 없으므로 초점을 얻지 못할 것입니다 (/ 정말로 / 초점을 맞추려면 Focusable = True 설정). 그러나 이와 같은 시나리오에서 기억해야 할 핵심은 Stackpanel 이이 경우 ItemContainer 인 TreeViewItem의 자식 이라는 것입니다. Micah가 제안했듯이 itemcontainerstyle을 조정하는 것은 좋은 접근 방식입니다.

아마도 DataTemplates와 RelativeSouce 마크 업 확장을 사용하여 listviewitem을 찾는 datatrigger와 같은 것들을 사용하여 할 수 있습니다.


답변