【问题标题】:How can I keep input events from propagating to siblings of a grid?如何防止输入事件传播到网格的兄弟姐妹?
【发布时间】:2015-11-03 06:29:29
【问题描述】:

我有一个我的 Windows Phone 8 应用程序页面。该页面有一个根网格,其中有一个 Grid 元素,其中包含页面的正常控件。根网格中还有一个用户控件。 Grid 和 usercontrol 都在根网格中的 0,0 中。现在的问题是,当我让用户控件可见并使用它来显示一些“请稍候”信息时,包含应用程序所有正常控件的另一个网格仍然会获得触摸输入。

整个想法是,冗长的操作会导致用户控件显示为半透明背景和一条消息,请稍候。我想以某种方式将其设置为捕获所有输入,但没有任何效果。

这是用户控件:

<UserControl x:Class="UserControls.ProgressPopup" ...>
    <Grid Name="ContentArea" MinWidth="200" MinHeight="200"
          HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
          Margin="0" ManipulationStarted="ContentArea_ManipulationStarted"
          Tap="ContentArea_Tap"
          MouseLeftButtonDown="ContentArea_MouseLeftButtonDown">
        <Rectangle Opacity="0.85" Name="TheBackground" 
                   HorizontalAlignment="Stretch" 
                   VerticalAlignment="Stretch" 
                   Fill="{StaticResource PhoneBackgroundBrush}"/>
        <ProgressBar Background="Transparent" Opacity="1" x:Name="ProgressBar"
                     IsIndeterminate="{Binding bIsIndeterminate}"
                     HorizontalAlignment="Stretch" Width="auto" 
                     Height="12" Margin="0,-30,0,0"/>
        <TextBlock ... />
    </Grid>
</UserControl>

这是它在页面上的使用方式:

<phone:PhoneApplicationPage
    x:Class="AirMobility.Pages.MainPage"
    ... >

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid Background="Transparent" Margin="0" x:Name="PageStuff">
            ...
        </Grid>

        <usercontrols:ProgressPopup Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="WaitScreen" Visibility="Collapsed" Background="Transparent"/>
    </Grid>
</phone:PhoneApplicationPage>

当名为“WaitScreen”的用户控件变为可见时,“PageStuff”网格和其中的控件仍会获得输入。该网格内部是一个枢轴控件,并且枢轴控件的页面仍然可以滚动。我试图获取 ManipulationStarted 事件并设置 e.handler=true 以停止传播,但它不起作用。似乎没有任何效果。

关于如何在用户控件或页面 xaml 中的用户控件定义中处理此问题的任何想法?我只是不想以某种方式在每个具有这些“WaitScreen”用户控件之一的页面上添加一堆事件处理程序。

[编辑...]

我尝试了用户控件的这种变体,但仍然无法正常工作:

<UserControl x:Class="UserControls.ProgressPopup"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
    FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeLarge}">

    <Grid Name="ContentArea" MinWidth="200" MinHeight="200" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0" Background="#01808080">
        <Grid Name="TheBackground" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#80204080"/>
        <ProgressBar Background="Transparent" Opacity="1" x:Name="ProgressBar"
            IsIndeterminate="{Binding bIsIndeterminate}" HorizontalAlignment="Stretch" Width="auto" Height="12" Margin="0,-30,0,0"/>
        <TextBlock Name="textBlock" Foreground="{StaticResource PhoneForegroundBrush}" Text="{Binding Text}" MinWidth="200" TextAlignment="Center"
            Opacity="1" Margin="0,14,0,0" VerticalAlignment="Center" HorizontalAlignment="Stretch" Height="40" FontSize="{Binding Source={StaticResource PhoneFontSizeNormal}}" FontFamily="{Binding Source={StaticResource PhoneFontFamilyNormal}}" />
    </Grid>
</UserControl>

底层枢轴仍然可以移动。

【问题讨论】:

  • 添加点击事件处理程序后,看起来点击没有通过。剩下的唯一症状就是usercontrol下的pivot控件仍然可以拖动/滑动来换页。

标签: c# xaml silverlight windows-phone-8 user-controls


【解决方案1】:

如果 WaitScreen 是透明的,则触摸事件可以通过。

大编辑将叠加层放入 PopupControl

  1. 我建议您用户控件中添加一个overlayGrid,但用户控件的内容下 - 顺序很重要

该控件是半透明 (Background="#80204080"),因此它应该捕获鼠标事件而不是让它们流到后面。

<UserControl x:Class="..." ... />
    <Grid x:Name="popupLayoutRoot">
        <Grid x:Name="overlayGrid" Background="#80204080" />
        <Grid x:Name="visiblePopupContent"  
              HorizontalAlignment="Center" 
              VerticalAlignment="Center" >
            <TextBlock  Text="Action in progress..."                               
                        HorizontalAlignment="Center" 
                        VerticalAlignment="Center"  />
        </Grid>
    </Grid>

overlayGrid 和 visiblePopupContent 不能是父子,而是兄弟。

  1. 在 Waitscreen 可见时使 Usercontrol 可见:
<phone:PhoneApplicationPage>
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid Background="Transparent" Margin="0" x:Name="PageStuff">
        </Grid>
        <usercontrols:ProgressPopup Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="WaitScreen" Visibility="Collapsed" Background="Transparent"/>
    </Grid>
</phone:PhoneApplicationPage>

这里是完整工作解决方案的链接:http://1drv.ms/1lm6jwN

问候

【讨论】:

  • 我需要将所有 ProgressPopup 代码和 XAML 保留在 ProgressPopup 中,以便随时在任何页面上重用它。通过此更改,我最终需要向使用弹出窗口的每个页面添加更多代码。另外,它没有用。我什至让 if 开始时可见,我仍然可以拖动枢轴控件的内容。但这是个好主意。
  • 刚刚做了一个大的编辑,使 UserControl 可重用
  • @David,对你有用吗?
  • 这个答案不能解决问题。我同意它应该解决问题,但放置任何不透明的网格不会阻止枢轴控件接受和执行拖动手势。由于我无法点击按钮并进行这项工作,因此我怀疑操作系统中发生了一些奇怪的事情。即使是页面本身上的 Grid 元素(不在用户控件中)也没有隐藏底层枢轴控件的手势!
  • 大卫,对我来说,它与下面的枢轴控件完美配合。我已经编辑了我的帖子以添加指向有效解决方案的链接。主页上有按钮显示用户控件2s或3s。在此期间,没有可能的手势或单击到枢轴。看它。我会很高兴你告诉我它有效。
【解决方案2】:

我尝试在页面本身而不是用户控件中添加另一个 元素,以始终覆盖 Pivot Control。我对其进行了硬编码,使其具有#80ff0000 的背景色,并且通过粉红色,我仍然可以移动枢轴控件。

我的解决方案违反了将所有弹出代码保留在弹出窗口中的愿望,涉及在等待屏幕可见时为枢轴控件设置 IsHittestVisible=false。这并不理想,因为其他页面不使用枢轴控件,因此需要特定于页面的“ShowWaitScreen()”方法。我不喜欢代码冗余,但现在必须这样做。

我认为 Pivot Control 正在获取某种我无法在叠加层中捕获的手势或触摸事件。也许操作系统正在做一些特别的事情,这让我很烦恼,或者我只是在我还没有发现的地方做错了什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    • 2019-05-06
    相关资源
    最近更新 更多