Выбор объекта на холсте WPF? - PullRequest
0 голосов
/ 23 февраля 2009

У меня есть холст WPF с некоторыми объектами эллипса (отображаются в виде кругов). Каждый круг взят из экземпляра класса коллекции, который на самом деле является классом пользовательского шаблона отверстия. Каждый шаблон имеет определенное количество кругов, и каждый круг затем добавляется на холст с помощью итерации по коллекции с использованием приведенного ниже кода.

Итак, холст заполняется группой кругов, и каждый круг принадлежит определенному экземпляру шаблона. Вы можете увидеть скриншот здесь: http://twitpic.com/1f2ci/full

Теперь я хочу добавить возможность щелкать по кругу на холсте и иметь возможность определять коллекцию, к которой он принадлежит, чтобы затем я мог выполнить еще несколько работ с выбранным рисунком, к которому принадлежит этот круг.

public void DrawHoles()
{
   // Iterate over each HolePattern in the HolePatterns collection... 
   foreach (HolePattern HolePattern in HolePatterns)
    {
        // Now iterate over each Hole in the HoleList of the current HolePattern...
        // This code adds the HoleEntity, HoleDecorator, and HoleLabel to the canvas
        foreach (Hole Hole in HolePattern.HoleList)
        {

            Hole.CanvasX = SketchX0 + (Hole.AbsX * _ZoomScale);
            Hole.CanvasY = SketchY0 - (Hole.AbsY * _ZoomScale);
            canvas1.Children.Add(Hole.HoleEntity);
        }
    }
}

Ответы [ 3 ]

3 голосов
/ 24 февраля 2009

Все FrameworkElements имеют свойство Tag, которое имеет тип объекта, который может использоваться для хранения произвольной информации. Вы можете присвоить HolePattern свойству Tag и легко использовать его позже для получения связанной коллекции.

т.е:.

...
Hole.HoleEntity.Tag = HolePattern as object;
canvas1.Children.Add(Hole.HoleEntity);

позже в событии щелчка:

event(object sender,....)
{
   Ellipse e = sender as Ellipse;
   HolePattern hp = e.Tag as HolePattern;
   ...
}
0 голосов
/ 24 февраля 2009

Я думал, что опубликую свое окончательное и более утонченное решение на случай, если оно кому-нибудь поможет.

void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    int ClickMargin = 2;// Adjust here as desired. Span is in both directions of selected point.
    var ClickMarginPointList = new Collection<Point>();
    Point ClickedPoint = e.GetPosition(canvas1);
    Point ClickMarginPoint=new Point();
    for (int x = -1 * ClickMargin; x <= ClickMargin; x++)
    {
        for (int y = -1 * ClickMargin; y <= ClickMargin; y++)
        {
            ClickMarginPoint.X = ClickedPoint.X + x;
            ClickMarginPoint.Y = ClickedPoint.Y + y;
            ClickMarginPointList.Add(ClickMarginPoint);
        }
    }

    foreach (Point p in ClickMarginPointList)
    {
        HitTestResult SelectedCanvasItem = System.Windows.Media.VisualTreeHelper.HitTest(canvas1, p);
        if (SelectedCanvasItem.VisualHit.GetType().BaseType == typeof(Shape))
        {
            var SelectedShapeTag = SelectedCanvasItem.VisualHit.GetValue(Shape.TagProperty);
            if (SelectedShapeTag!=null &&  SelectedShapeTag.GetType().BaseType == typeof(Hole))
            {
                Hole SelectedHole = (Hole)SelectedShapeTag;
                SetActivePattern(SelectedHole.ParentPattern);
                SelectedHole.ParentPattern.CurrentHole = SelectedHole;
                return; //Get out, we're done.
            }
        }
    }
}
0 голосов
/ 24 февраля 2009

Так что вы, наверное, уже прочитали мой ответ, где я сказал, что у меня это работает. И он работает отлично (за исключением того, что требует большой точности с помощью мыши), но я хочу спросить: действительно ли разумно добавлять обработчик событий в КАЖДЫЙ эллипс, который добавляется на холст? Теперь я не знаю, что это за память, или, может быть, для WPF и Windows это очень просто.

В практическом случае, я думаю, было бы не более 30-50 отверстий даже на экране с несколькими рисунками, но все же; FIFTY обработчики событий? Это просто кажется страшным. И на самом деле каждая «дыра» визуально представлена ​​двумя концентрическими кружками и текстовой меткой (см. Скриншот здесь: http://twitpic.com/1f2ci/full), и я знаю, что пользователь может ожидать нажатия на любой из этих элементов. выбрать отверстие. Это означает, что обработчик событий на 3 элемента для каждого отверстия. Теперь мы можем говорить о 100 или более обработчиках событий.

Похоже, что должно быть решение, в котором вы могли бы иметь только один обработчик событий на Canvas и читать ссылку на элемент под мышью, затем обрабатывать это, чтобы получить свойство .Tag этого элемента, и так далее.

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