【问题标题】:Tap event on dynamically added custom control is handled by another control of same type动态添加的自定义控件上的点击事件由另一个相同类型的控件处理
【发布时间】:2013-09-11 19:21:45
【问题描述】:

我的自定义控件 Waypoint 的事件由相同类型的另一个自定义控件处理时遇到问题。

概述

我正在努力将这些 Waypoint 自定义控件放到另一个自定义控件 MapUserControl 上,该控件以地图为背景。

这是我目前拥有的照片

这是 Waypoint 自定义控件的 XAML:

<UserControl x:Name="MyWaypointControl" x:Class="MADAssignment1.Waypoint"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="35" d:DesignWidth="35" Opacity="0.5"
         Tap="Waypoint_Tap">

<UserControl.Resources>
    <Storyboard x:Name="FadeInStoryBoard">
        <DoubleAnimation
                    Storyboard.TargetName="MyWaypointControl"
                    Storyboard.TargetProperty="Opacity"
                    From="0.0" To="0.5" Duration="0:0:0.3"
                    AutoReverse="False"/>
    </Storyboard>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Ellipse x:Name="BackgroundCircle" Fill="Blue" HorizontalAlignment="Left" Height="35" Margin="0,0,0,0" Stroke="Black" VerticalAlignment="Top" Width="35"/>
    <TextBlock x:Name="NumberLabel" HorizontalAlignment="Left" TextAlignment="Center" Margin="4,6,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Height="22" RenderTransformOrigin="0.211,0.467" FontSize="15" Width="26"/>
</Grid>

这是 MapUserControl 自定义控件的 XAML:

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MADAssignment1" x:Name="MapUserControl" x:Class="MADAssignment1.Map"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="531" d:DesignWidth="493" SizeChanged="MapUserControl_SizeChanged">

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Image x:Name="MapImage" Height="532" VerticalAlignment="Top" Source="/Assets/background image.jpg" Stretch="Fill" Loaded="MapImage_Loaded"/>
    <TextBlock x:Name="MinLongitudeLabel" HorizontalAlignment="Left" Margin="33,0,0,511" TextWrapping="Wrap" Text="" VerticalAlignment="Top" FontSize="15"/>
    <TextBlock x:Name="MiddleLongitudeLabel" HorizontalAlignment="Left" Margin="200,0,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" FontSize="15"/>
    <TextBlock x:Name="MaxLongitudeLabel" HorizontalAlignment="Left" Margin="382,0,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" FontSize="15"/>
    <TextBlock x:Name="MinLatitudeLabel" HorizontalAlignment="Left" Margin="4,21,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" FontSize="15"/>
    <TextBlock x:Name="MiddleLatitudeLabel" HorizontalAlignment="Left" Margin="4,250,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" FontSize="15"/>
    <TextBlock x:Name="MaxLatitudeLabel" HorizontalAlignment="Left" Margin="4,512,0,-1" TextWrapping="Wrap" Text="" VerticalAlignment="Top" FontSize="15"/>
</Grid>

如您所见,它们都相当简单。

问题

当我点击航点时,它们并不总是按预期工作,我会说它是 ~50/50。

这是 Waypoint_Tap 的事件处理程序:

    private void Waypoint_Tap(object sender, GestureEventArgs e)
    {
        BackgroundCircle.Fill = new SolidColorBrush(Colors.Red);
    }

再次,简单。

问题在于事件处理程序中的发送者对象并不总是我点击的 Waypoint,而是始终是地图上的另一个 Waypoint。

以下是重现问题的步骤。

  1. 我点击 Waypoint #7,事件处理程序的发送者是 Waypoint #7 用户控件,所以它变成了红色。
  2. 我点击 Waypoint #2,事件处理程序的发送者又是 Waypoint #7,所以它变成了红色。
  3. 每当我点击 Waypoint #2 时,Waypoint #7 都会变成红色。

现在看到我正在动态添加路点,我认为这可能会导致问题,所以这是我如何将路点添加到 MapUserControl 用户控件:

        var newWaypoint = new Waypoint(waypointNumber, latitude, longitude);
        newWaypoint.Name = "wayPoint" + waypointNumber;
        newWaypoint.Opacity = 100;
        double leftMargin = CalculateLeftMargin(longitude);
        double topMargin = CalculateTopMargin(latitude);

        newWaypoint.Margin = new Thickness(leftMargin, topMargin, 0, 0);
        LayoutRoot.Children.Add(newWaypoint);

我还认为可能是 GestureEventArgs 正在冒泡/连接到另一个控件,但我无法确定,因为我找不到它使用的 RoutingStrategy 类型。

我真的很希望像MSDN 所说的那样直接路由策略

直接:只有源元素本身有机会调用处理程序作为响应。这类似于 Windows 窗体用于事件的“路由”。

我相信我已经设置了 Waypoint 以使用 Windows 窗体之类的事件,但我只能希望。

【问题讨论】:

    标签: c# xaml events windows-phone-8 wpf-controls


    【解决方案1】:

    我发现了问题所在,但我将其归咎于缺乏 WPF 经验。

    当我创建我的航点时,我喜欢创建它们

    var newWaypoint = new Waypoint(waypointNumber, latitude, longitude);
    newWaypoint.Name = "wayPoint" + waypointNumber;
    newWaypoint.Opacity = 100;
    double leftMargin = CalculateLeftMargin(longitude);
    double topMargin = CalculateTopMargin(latitude);
    
    newWaypoint.Margin = new Thickness(leftMargin, topMargin, 0, 0);
    LayoutRoot.Children.Add(newWaypoint);
    

    问题在于我设置了控件的边距。当我设置边距时,它实际上是在扩展我的航点,所以我在航点上放置了航点。

    经过一番研究,我发现了这篇文章 Changing Position of an Element Programmatically in WPF,它向我展示了如何在 WPF 中正确定位 UI 元素,而不是设置控件的边距。

    【讨论】:

      猜你喜欢
      • 2019-09-16
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-08
      • 1970-01-01
      相关资源
      最近更新 更多