5

我有一个 Silverlight 应用程序,它显示ListBox. 每个项目代表我的应用程序的不同“页面”,因此我有一个应用于ItemContainerStyle属性的样式,如下所示:

<Style x:Key="navigationItemContainerStyle" TargetType="ListBoxItem">
    <Setter Property="Margin" Value="5,3"/>
    <Setter Property="FontSize" Value="16"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Grid Cursor="Hand">
                    <VisualStateManager.VisualStateGroups>
                        <!-- code omitted --!> 
                    </VisualStateManager.VisualStateGroups>
                    <Border x:Name="contentBorder"
                            Background="{StaticResource navigationHighlightBrush}" 
                            CornerRadius="3"
                            Opacity="0"/>
                    <ContentControl x:Name="content"
                                    Margin="10,5"
                                    Content="{Binding}" 
                                    Foreground="DarkGray"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

风格非常简单。BorderListBoxItem' 的视觉状态等于 'Selected'时,它只显示。请注意,内容由 a 托管,ContentControl因为我希望能够Foreground在项目处于“已选择”状态时更改属性。

从下面的屏幕截图可以看出,这非常有效:

在此处输入图像描述

现在我希望所选项目调用导航,所以我的想法是创建一个DataTemplate将每个项目的内容设置为 a HyperLinkButton

<DataTemplate x:Key="navigationListBoxItemTemplate">
    <HyperlinkButton Content="{Binding}" 
                     Background="Transparent"/>
</DataTemplate>

现在这不适用于它的内容在 a而不是 a中的ItemTemplate主机,所以我不得不更新模板以使用 a代替。ContentControlContentPresenterListBoxItemContentPresenter

<ContentPresenter x:Name="content" Margin="10,5"/>

我现在得到以下结果:

在此处输入图像描述

当我点击现在不再被选中(我可以点击外面HyperLinkButton并且被选中)。我真正想要的是在单击时被选中。没有选择的 概念,所以我不能绑定到'属性。ListBoxItemHyperLinkButtonListBoxItemListBoxItemHyperLinkButtonHyperLinkButtonListBoxItemIsSelected

注意:实际导航效果很好,问题纯粹是ListBoxItems.

所以我的问题是:

  1. 我可以这样做,以便在HyperLinkButton单击时,ListBoxItem像第一张图片一样被选中?
  2. 我还需要一些方法来改变HyperLinkButton它被选中时的前景,因为我在项目模板中不再这样做,因为我交换了ContentControlfro a ContentPresenter

注意:我可能可以通过将 的SelectedItem属性绑定ListBox到我的 viewModel 并处理那里的导航来解决这个问题,从而否定HyperLinkButton每个主机托管的要求,ListBoxItem但我很想知道是否可以使用样式和模板来实现我想要的结果.

更新

我已经尝试了几件事来尝试解决这个问题,但到目前为止都没有成功。我尝试的第一件事是对HyperLinkButton我的控件应用一种新样式,DataTemplate这基本上从控件中删除了所有默认外观,但我的应用程序仍然以上述方式运行。

我尝试的第二件事是将IsHitTestVisible属性设置为 false。这允许我单击“通过”HyperLinkbutton并选择,ListBoxItem但这意味着现在不再调用导航。

4

1 回答 1

0

未选择 ListBoxItem,因为 Button(无论它是什么类型)将 MouseLeftButtonDown 事件标记为 Handled。因此,所需的事件不会冒泡到父 ListBoxItem。

显然,您的 ListBoxItem 正在从单击中获得焦点(我假设这是您最终图像中的边框),因此无论如何都必须发生这种情况。

在幕后,ListBoxItem 将设置一个标准的 LeftMouseButtonDown 事件处理程序来处理选择,并且它必须调用 AddHandler 来处理设置焦点。


您可以通过为事件添加自己的处理程序来实现类似的效果,如下所示:

 listboxitem.AddHandler(UIElement.MouseLeftButtonDownEvent, new System.Windows.Input.MouseButtonEventHandler(MyMouseLeftButtonDownEventHandler), true);

最后一个参数指示处理程序处理已处理的事件......

附加这个我留给你的处理程序,但使用行为可能是最直接的。您可以事件从 Button 派生一个类型,并让它沿着 Visual Tree 查找并选择 ListBoxItem……可能性是无穷无尽的。

于 2013-02-05T07:20:08.793 回答