【问题标题】:WPF ControlTemplate Triggers [closed]WPF ControlTemplate 触发器 [关闭]
【发布时间】:2017-09-05 17:48:28
【问题描述】:

我有一个使用 WPF、C# 和所有好东西(Visual Studio 2010 也是)的项目。

我有一个 WPF ListBox,并且在该 ListBox 中,有一个 ListBoxItem 的控件模板。其中有一个触发器部分。

在这种特殊情况下,触发器属性是 IsSelected,指的是 ListBox 的选定项。

我希望做的是通过将其从 ListBox 控件中取出并将其放入资源列表中的 ControlTemplate 中来进行清理。

当我这样做时,它正确地告诉我框架元素中没有“IsSelected”。

有人可以就如何完成这项工作提出一些建议吗?

谢谢。

哦,XAML 代码在这里:

<ControlTemplate.Triggers>
                <Trigger Property="IsSelected" Value="true">
                    <Setter TargetName="_Border" Property="Effect">
                        <Setter.Value>
                            <DropShadowEffect ShadowDepth="0" Color="Black" Opacity="1" BlurRadius="20" />
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </ControlTemplate.Triggers>

编辑:我确实尝试过:

<Trigger Property="{Binding Path=IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}" Value="true">

但是,我收到一条错误消息,提示“无法在“触发器”类型的“属性”属性上设置“绑定”。

额外编辑:好的,这是 ListBox 的 XAML:

<ListBox ItemsSource="{Binding ChatNodeListViewModel.ChatNodeVMs, Source={StaticResource Locator}}" Background="Transparent" Name="LbNodes" SelectedItem="{Binding ChatNodeListViewModel.SelectedNode, Source={StaticResource Locator}}" >
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas HorizontalAlignment="Left" VerticalAlignment="Top" Width="2000" Height="1600"/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListBoxItem">

                                <Border x:Name="_Border" Padding="1" SnapsToDevicePixels="true" BorderThickness="3" Margin="2" CornerRadius="5,5,5,5" BorderBrush="{Binding IsHeadNode, Converter={StaticResource ResourceKey=HeadNodeToLinearGradientBrushConverter}}" >

                                    <ContentPresenter />
                                </Border>

                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsSelected" Value="true">
                                        <Setter TargetName="_Border" Property="Effect">
                                            <Setter.Value>
                                                <DropShadowEffect ShadowDepth="0" Color="Black" Opacity="1" BlurRadius="20" />
                                            </Setter.Value>
                                        </Setter>
                                    </Trigger>
                                </ControlTemplate.Triggers-->
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>

                    <Setter Property="Canvas.Left" Value="{Binding XCoord}"/>
                    <Setter Property="Canvas.Top" Value="{Binding YCoord}"/>
                    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="lb_PreviewMouseLeftButtonDown" />

                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Thumb Name="myThumb" Template="{StaticResource NodeVisualTemplate}">

                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="DragDelta">
                                    <cmd:EventToCommand Command="{Binding ChatNodeListViewModel.DragDeltaCommand, Source={StaticResource Locator}}" PassEventArgsToCommand="True"/>
                                </i:EventTrigger>

                            </i:Interaction.Triggers>
                        </Thumb>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

因此,如果您查看此处的控件模板触发器,它会应用于边框(称为“_Border”)。现在的问题是,这让我的边框与 ListBoxItem 的控件模板(称为 NodeVisualTemplate)分开。我想将该边框放入 NodeVisualTemplate 中,但我不确定如何将该链接保留到 IsSelected 属性。这就是问题的根源。

【问题讨论】:

  • 这似乎是 ListBoxItem 模板的一部分,而不是 ListBox。
  • 你需要共享更多的 XAML,也许是整个 ControlTemplate。可能是 ListBox 的整个 XAML。
  • 对不起,我已经更新了一些更多信息。
  • 在 Thumb 模板中,尝试&lt;DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxITem}}" Value="true"&gt;
  • 您应该将其写为@EdPlunkett 的答案之一,这样我就可以将其勾选为正确。我不知道不同类型的触发器或者它们可以互换(尽管我认为还有更多的微妙之处)。

标签: c# wpf xaml listbox


【解决方案1】:

Trigger 只允许您命名您正在模板化的控件的属性或(如果它是样式触发器)样式,但DataTrigger 让您触发您可以从Binding 获得的任何值。

这要强大得多。 WPF 的Binding 类可以做很多不同的事情。我会在Thumb 模板中尝试,使用RelativeSource 搜索可视树以找到最近的ListBoxItem 类型的父控件,然后获取该ListBoxItem 的IsSelected 属性值。生成的Thumb 模板仅对属于 ListBoxItems 的 Thumb 非常有用,但没关系。

<DataTrigger 
    Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}" 
    Value="true"
    >
    ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-31
    • 2018-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多