如何在不触发Tap的情况下可靠地更改WP7 ListBox上的SelectedItem?

时间:2013-06-20 09:49:43

标签: windows-phone-7 listbox

我的WP7应用程序中有一个ListBox,它有一个ItemTemplate用于它的项目。

模板如下所示:

<DataTemplate x:Key="TapCountryItemTemplate">
    <Grid Margin="12,6,12,6" Tap="OnTapped">
        <Rectangle Fill="Yellow" /> 
        <TextBlock Text="{Binding Country}" 
             FontSize="{StaticResource PhoneFontSizeExtraLarge}" />
    </Grid>
</DataTemplate>

这是结果的图像:

Selection Screenshot

如果您慢慢按下列表项目的右侧,(因此不是点按),当您抬起手指时,列表框中的选项会发生变化。

但是,如果您在黄色区域执行相同的操作,则不会更改选择,但项目会倾斜。

您可以在我们的应用中看到行动中的行为(不带黄色): http://www.wieser-software.com/m/travel

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

只是一个简单的问题:为什么要处理Grid Tap而不是ListBox SelectionChanged?

据我所知,SelectionChanged导致选择,Tap导致导航到所需的详细信息页面

如果你想使用Tap而不是SelectionChanged将TextBlock设置为Horizo​​ntalAlignment to Stretch,那么Grid占据全宽

答案 1 :(得分:1)

这里有两个相互竞争的事情。

  1. 您希望在列表中指明某个项目在某个时刻与其他项目不同。也就是说,它被“选中”。选择某个项目时,您允许将前景色的默认行为更改为强调色以表明这一点。

  2. 您希望允许用户点按某个项目以触发导航到与所点击的项目相关的其他页面。

  3. 通过查看您的应用,您似乎正在使用所选状态来指示最后选择的项目(国家/地区)。我会质疑这个的价值(人们不记得他们只是在看什么)但这是你的选择。

    那么,这里到底发生了什么?

    • 当您触摸TextBlock但未触发外部控件中的Tap事件时,触摸事件将丢失,并且不会冒泡到ListBoxItem以触发选定的状态更改。

    • 当您触发Tap事件时,触摸也会冒泡到ListBoxItem并更改所选状态。

    • 由于网格的宽度仅与其内容(TextBlock)一样宽,因此可以触摸网格外部的ListBoxItem并触发所选项目的更改。你确实得到了倾斜,因为它是在ListBoxItem而不是Grid上设置的。

    通过确保Grid占用ListBoxItem占用的整个空间(宽度),您可以避免意外行为(在不触发敲击事件时选择更改)。最简单的方法是设置Grid的宽度。

    然而。
    如果它是我,我想要一种方式来指示最后查看的项目,我不会依赖于ListBox中的项目的选择状态保持同步正确(包括跨墓碑)但是会向底层视图模型添加属性通过仅在触发点击事件和导航时更改它,我将使用它来手动跟踪它。然后可以在代码中(或通过绑定上的转换器)设置最近选择的项目的颜色。这样做可以在任何时候完全控制UI的外观。

答案 2 :(得分:0)

根据马特的建议,这就是我如何实现我想要的目标:

  1. 点击事件导航到用户建议的页面

  2. 不点击仍会选择该项目,因此如果您慢慢地选择该项目,或者向右滑动,我会选择该项目。

  3. 首先,我必须让我的网格延伸。 Matt建议设置一个宽度,但我之前在Silverlight中使用过这个技巧:

    <Style x:Name="Stretchy" TargetType="ListBoxItem" >
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    </Style>
    

    并相应地设置我的ListBox:

    <ListBox ItemContainerStyle="{StaticResource Stretchy}" .../>
    

    最后,在我的DataTemplate(上面)中,我为

    添加了一个处理程序
    MouseLeftButtonUp="ButtonUp" 
    

    并在后面的代码中实现它(但你可以用行为来实现),如下所示:

    private void ButtonUp(object sender, MouseButtonEventArgs e)
    {
        // set the selected item to the data context, which forces the listbox to highlight correctly
        App.VM.SelectedCountry = ((sender as FrameworkElement).DataContext) as CountryData;
    }
    

    请注意,根据控件中的其他xaml,处理ButtonUp事件可能很困难。为了解决这个问题,我将整个控件覆盖在一个不同的项目中,其矩形的不透明度为0.01,并将事件附加到矩形而不是网格。