列表框项目的 DataTemplate 中 IsSelected 的 WPF 触发器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/248545/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 19:44:49  来源:igfitidea点击:

WPF Trigger for IsSelected in a DataTemplate for ListBox items

wpftriggerslistboxitemtemplateevent-triggers

提问by TimothyP

I have a listbox, and I have the following ItemTemplate for it:

我有一个列表框,我有以下 ItemTemplate:

<DataTemplate x:Key="ScenarioItemTemplate">
    <Border Margin="5,0,5,0"
            Background="#FF3C3B3B"
            BorderBrush="#FF797878"
            BorderThickness="2"
            CornerRadius="5">
        <DockPanel>
            <DockPanel DockPanel.Dock="Top"
                       Margin="0,2,0,0">
                <Button HorizontalAlignment="Left"
                        DockPanel.Dock="Left"
                        FontWeight="Heavy"
                        Foreground="White" />
                <Label Content="{Binding Path=Name}"
                       DockPanel.Dock="Left"
                       FontWeight="Heavy"
                       Foreground="white" />
                <Label HorizontalAlignment="Right"
                       Background="#FF3C3B3B"
                       Content="X"
                       DockPanel.Dock="Left"
                       FontWeight="Heavy"
                       Foreground="White" />
            </DockPanel>
            <ContentControl Name="designerContent"
                            Visibility="Collapsed"
                            MinHeight="100"
                            Margin="2,0,2,2"
                            Content="{Binding Path=DesignerInstance}"
                            Background="#FF999898">
            </ContentControl>
        </DockPanel>
    </Border>
</DataTemplate>

As you can see the ContentControl has Visibility set to collapsed.

如您所见,ContentControl 已将 Visibility 设置为折叠。

I need to define a trigger that causes the Visibility to be set to "Visible"

我需要定义一个触发器,导致可见性设置为“可见”

when the ListItem is selected, but I can't figure it out.

当 ListItem 被选中时,但我无法弄清楚。

Any ideas?

有任何想法吗?

UPDATE: Of course I could simply duplicate the DataTemplate and add triggers to the ListBox in question to use either one or the other, but I want to prevent duplicating this code.

更新:当然,我可以简单地复制 DataTemplate 并将触发器添加到有问题的 ListBox 以使用其中一个或另一个,但我想防止复制此代码。

回答by Matt Hamilton

You can style your ContentControl such that a trigger fires when its container (the ListBoxItem) becomes selected:

您可以设置 ContentControl 样式,以便在其容器(ListBoxItem)被选中时触发触发器:

<ContentControl 
    x:Name="designerContent"
    MinHeight="100"
    Margin="2,0,2,2"
    Content="{Binding Path=DesignerInstance}"
    Background="#FF999898">
    <ContentControl.Style>
        <Style TargetType="{x:Type ContentControl}">
            <Setter Property="Visibility" Value="Collapsed"/>
            <Style.Triggers>
                <DataTrigger
                        Binding="{Binding
                            RelativeSource={RelativeSource
                                Mode=FindAncestor,
                                AncestorType={x:Type ListBoxItem}},
                                Path=IsSelected}"
                        Value="True">
                    <Setter Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

Alternatively, I think you can add the trigger to the template itself and reference the control by name. I don't know this technique well enough to type it from memory and assume it'll work, but it's something like this:

或者,我认为您可以将触发器添加到模板本身并按名称引用控件。我不太了解这种技术,无法从内存中键入它并假设它会起作用,但它是这样的:

<DataTemplate x:Key="ScenarioItemTemplate">
    <DataTemplate.Triggers>
        <DataTrigger
                Binding="{Binding
                    RelativeSource={RelativeSource
                        Mode=FindAncestor,
                        AncestorType={x:Type ListBoxItem}},
                        Path=IsSelected}"
                Value="True">
            <Setter
                TargetName="designerContent"
                Property="Visibility"
                Value="Visible"/>
        </DataTrigger>
    </DataTemplate.Triggers>

    ...
</DataTemplate>

回答by TimothyP

@Matt, Thank you!!!

@马特,谢谢!!!

Just had to add a trigger for IsSelected == false as well, and now it works like a charm!

只需要为 IsSelected == false 添加一个触发器,现在它就像一个魅力!

<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
    <Setter Property="Visibility" Value="Collapsed"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="True">
            <Setter Property="Visibility" Value="Visible"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="False">
            <Setter Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
    </Style.Triggers>
</Style>