Почему мой путь не отображается, когда я программно добавляю сегменты к пути в Silverlight 2? - PullRequest
4 голосов
/ 30 октября 2008

Я создаю Path в Silverlight и добавляю в него элементы при событиях мыши. Но, хотя элементы находятся в памяти, экран не обновляется, пока что-то еще не вызовет перерисовку экрана.

Вот соответствующий код - я отвечаю на событие мыши и сохраняю член класса пути, который я редактирую.

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 и InvalidateArrange на Path (и на родительской сетке) безрезультатно.

Единственный обходной путь, который у меня есть, - это изменить свойство пути, а затем изменить его обратно, чего, по-видимому, достаточно, чтобы механизм рендеринга нарисовал новые элементы пути. Я использую Opacity. Вы должны установить другое значение, иначе (я полагаю) событие PropertyChanged не сработает. Хотя это клудж.

Кто-нибудь еще играл с путями таким образом? Думаю, если бы я одновременно выводил на экран другие графические элементы, это не было бы проблемой, так что, вероятно, это не что-то, что могло бы повлиять на людей, но было бы хорошо знать, если есть более правильный способ сделать это .

Ответы [ 2 ]

1 голос
/ 12 мая 2009

Мне нужно было что-то очень похожее, но я рисовал на новом 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 работают так, как вы ожидаете. Я могу помочь кому-то еще, я надеюсь ...

0 голосов
/ 30 октября 2008

Какой элемент является вашим корневым макетом? Я скопировал ваш код и использовал 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, который ничего не делает. Когда я нажимаю на экран, я получаю новые линии, нарисованные до точки, которую я щелкнул.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...