当我以编程方式将段添加到Silverlight 2中的路径时,为什么我的路径不显示?

时间:2008-10-30 11:30:41

标签: c# silverlight

我在 Silverlight 中创建Path,并在鼠标事件上添加元素。但是,虽然元素存在于内存中,但屏幕不会更新,直到其他内容导致屏幕重绘发生。

这是相关的代码 - 我正在响应鼠标事件,并且我保留了我正在编辑的路径的类成员。

Path path = null;

private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Point thisPoint = e.GetPosition(LayoutRoot);
    if (path == null)
    {
        CreateNewPath(thisPoint);
        path.LayoutUpdated += new EventHandler(path_LayoutUpdated);
    }
    else
    {
        path.AddLineElement(thisPoint);
    }
}

private void CreateNewPath(Point startPoint)
{
    path = new Path();
    PathGeometry geometry = new PathGeometry();
    path.Data = geometry;
    PathFigureCollection figures = new PathFigureCollection();
    geometry.Figures = figures;
    PathFigure figure = new PathFigure();
    figures.Add(figure);
    figure.StartPoint = startPoint;
    figure.Segments = new PathSegmentCollection();
    path.Stroke = new SolidColorBrush(Colors.Red);
    path.StrokeThickness = 2;
    path.Stretch = Stretch.None;
    LayoutRoot.Children.Add(path);
}

AddLineElement是路径类的扩展方法,只是为了简化:

public static class PathHelper
{
    public static void AddLineElement(this Path thePath, Point newPoint)
    {
        PathGeometry geometry = thePath.Data as PathGeometry;
        geometry.Figures[0].Segments.Add(new LineSegment { Point = newPoint });
    }
}

这是重现问题所需的最低要求。如果您在完整的WPF应用程序中运行此代码,它将按预期工作。鼠标单击添加立即出现的线元素。但是,在 Silverlight 中,这是另一回事。点击似乎什么都不做,即使单步执行代码显示数据已添加。但是,如果您单击几次,然后调整浏览器的大小,例如,将显示路径元素。如果您碰巧在页面上有一个按钮,并将鼠标移到上面,则会显示路径。

我已经尝试过所有明显的事情,例如在InvalidateMeasure(和父网格)上调用InvalidateArrangePath无济于事。

我唯一的解决方法是更改​​路径上的属性然后将其更改回来,这似乎足以让渲染引擎绘制新的路径元素。我使用Opacity。你必须将它设置为不同的值,否则(我认为)PropertyChanged事件不会触发。不过,这是一块垃圾。

有没有其他人以这种方式玩过路径?我想如果我同时在屏幕上放置其他图形元素这不会是一个问题,所以它可能不会影响人们,但是知道是否有更正确的方法可以做到这一点会很好

2 个答案:

答案 0 :(得分:1)

我需要一些非常相似的东西,但是使用新的Silverlight VE Map Control。上面的代码工作正常,没有任何其他属性来“强制重绘”。这里的代码供您参考:

using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.VirtualEarth.MapControl;

namespace MapInfo
{
    public partial class Page : UserControl
    {
        /// <summary>
        /// Sample drawing a polyline on a Virtual Earth map
        /// </summary>
        public Page()
        {
            InitializeComponent();
            VEMap.MouseLeftButtonUp += new MouseButtonEventHandler(VEMap_MouseLeftButtonDown);
            VEMap.MouseLeave += new MouseEventHandler(VEMap_MouseLeave);
        }

        MapPolyline polyline = null;

        /// <summary>
        /// Ends drawing the current polyline
        /// </summary>
        void VEMap_MouseLeave(object sender, MouseEventArgs e)
        {
            polyline = null;
        }
        /// <summary>
        /// Start or add-to a polyline
        /// </summary>
        private void VEMap_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Map m = (Map)sender;

            Location l = m.ViewportPointToLocation(e.GetPosition(m));

            if (polyline == null)
            {
                CreateNewPolyline(l);
            }
            else
            {
                polyline.Locations.Add(l);
            }
        }
        /// <summary>
        /// Create a new MapPolyline
        /// </summary>
        /// <param name="startPoint">starting Location</param>
        private void CreateNewPolyline(Location startPoint)
        {
            polyline = new MapPolyline();
            polyline.Stroke = new SolidColorBrush(Colors.Red);
            polyline.StrokeThickness = 2;
            var lc = new LocationCollection();
            lc.Add(startPoint);
            polyline.Locations = lc;
            VEMap.Children.Add(polyline);
        }
    }
}

对您的直接场景没有帮助,但表明其他Silverlight的功能正如您所期望的那样。可能会帮助别人,我希望...

答案 1 :(得分:0)

您的布局根是什么类型的元素?我复制了你的代码,并使用Canvas作为布局根,它在IE和Firefox中都很好用。

<UserControl x:Class="SilverlightTesting.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
        <Canvas x:Name="LayoutRoot" Background="White" Width="400" Height="300" MouseLeftButtonDown="LayoutRoot_MouseLeftButtonDown"/>
</UserControl>

我复制了所有代码并创建了一个新的path_LayoutUpdated方法,该方法什么都不做。当我点击屏幕时,我得到新的线条画到我点击的位置。