如何正确使用列表框itemtemplate / datatemplate中的按钮?

时间:2013-01-08 12:57:06

标签: c# silverlight styles datatemplate

我有一个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>

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

这可以很好地工作,如下面的屏幕截图所示:

enter image description here

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

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

现在这不起作用,因为ItemTemplate托管了ContentControl而不是ContentPresenter的内容,所以我必须更新ListBoxItem模板才能使用而是ContentPresenter

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

我现在得到以下结果:

enter image description here

当我点击HyperLinkButton时,ListBoxItem现已不再被选中(我可以点击HyperLinkButton外部,ListBoxItem被选中)。我真正想要的是在点击ListBoxItem时选择HyperLinkButtonHyperLinkButton没有选择概念,因此我无法绑定到ListBoxItem的{​​{1}}属性。

注意:实际导航效果很好,问题纯粹是IsSelected的外观。

所以我的问题是:

  1. 我是否可以这样做,以便在点击ListBoxItems时,HyperLinkButton会像第一张图片一样被选中?
  2. 由于我将ListBoxItem换成HyperLinkButton,我还需要一些方法来更改ContentControl选中它的前景,因为项目模板中已不再这样做了}。
  3. 注意:我可以通过将ContentPresenter的{​​{1}}属性绑定到我的viewModel并在那里处理导航来解决此问题,从而无需使用{{由每个SelectedItem托管,但我有兴趣知道是否可以使用样式和模板来实现我想要的结果。

    更新

    我尝试了几件事来尝试解决这个问题,但到目前为止还没有成功。我尝试的第一件事就是将新样式应用到我ListBox中的HyperLinkButton控件中,这实际上从控件中删除了所有默认外观,但我的应用程序仍然按照上述方式运行。 / p>

    我尝试的第二件事是将ListBoxItem属性设置为false。这样,我就可以点击HyperLinkButton中的DataTemplate并选择IsHitTestVisible,但这意味着现在不再调用导航。

1 个答案:

答案 0 :(得分:0)

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

显然,你的ListBoxItem正从点击中获得焦点(我认为这是你最终图像中的边框),所以无论如何都必须这样做。

在封面下,ListBoxItem将设置一个标准的LeftMouseButtonDown事件处理程序来处理Selection,它必须调用AddHandler来处理设置焦点。


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

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

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

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