0

我的 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>

这是结果的图像:

选择截图

如果您慢慢按下列表项的右侧(所以它不是点击),当您抬起手指时,列表框中的选择会更改。

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

您可以在我们的应用程序中查看实际行为(没有黄色部分):http: //www.wieser-software.com/m/travel

有任何想法吗?

4

3 回答 3

1

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

  1. 您想在某个时刻将列表中的项目指示为与其他项目不同。即,它被“选中”。选择项目时,您允许将前景颜色的默认行为更改为重音颜色,以表明这一点。

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

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

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

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

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

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

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

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

于 2013-06-20T13:57:56.973 回答
1

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

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

如果你想使用 Tap 而不是 SelectionChanged 将 TextBlock 设置为 Horizo​​ntalAlignment 以 Stretch 以便 Grid 占据整个宽度

于 2013-06-20T09:57:00.787 回答
0

根据马特的建议,我是这样实现我想要的:

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

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

首先,我必须让我的网格扩展。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;
}

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

于 2013-06-20T14:33:21.460 回答