Pregunta

Estoy respondiendo a MouseLeftButtonDown eventos en elementos añadidos a un lienzo WPF. Todo funciona bien cuando se hace clic (es decir, el manejador de sucesos dispara correctamente), pero requiere demasiada precisión del puntero del ratón. Usted tiene que estar perfectamente en la parte superior del círculo para hacer que funcione. Necesito que sea un poco más indulgente; tal vez al menos 1 o 2 pixles indulgente. Los elementos en el lienzo son bonitas y grandes círculos (aproximadamente el tamaño de una moneda en la pantalla), por lo que los mismos círculos no son demasiado pequeñas, pero el anchoTrazo de cada uno es 1, por lo que es una línea delgada.

Se puede ver una captura de pantalla aquí: http://twitpic.com/1f2ci/full

La mayoría de los gráficos de aplicación no son de este exigente con la cosecha del ratón, así que quiero dar al usuario una experiencia familiar.

¿Cómo puedo hacer que sea un poco más indulgente.

¿Fue útil?

Solución

Puede conectar al evento MouseLeftButtonDown de la raíz del objeto de presentación en su lugar, y comprobar qué elementos está dentro del alcance de un clic al hacer esto:

List<UIElement> hits = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(Point, yourLayoutRootElement) as List<UIElement>;  

http://msdn.microsoft.com/ en-us / library / cc838402 (VS.95) .aspx

Para el parámetro Point, puede utilizar el parámetro MouseEventArgs e, y llamar a su método GetPosition como esto:

Point p = e.GetPosition(null)

No puedo recordar si se debe utilizar en lugar de los HitTest FindElementsInHostCoordinates. Pruebe ambos.
http://msdn.microsoft.com/en-us/library/ms608752. aspx

Se puede crear objetos Point 4 de la posición del ratón para crear un efecto tolerence falso, y llamar a cualquiera de FindElementsInHostCoordinates o HitTest de los 4 puntos.

Otros consejos

Es posible que desee para tratar de llenar el círculo con el color transparente para que el conjunto se puede hacer clic círculo ...

Si eso no funciona, también puede dibujar círculos ayudante en la misma ubicación que los otros círculos. Hacer que el color del círculo primer plano transparente, y hacer que el grosor del pincel de unos pocos píxeles más amplio para hacer clic en una región más aceptable alrededor del círculo ..

Espero que esto ayude!

Creo que lo he hecho (con ayudas a me refiero a) ...

En primer lugar, me he movido el manejo al lienzo y no de cada elipse evento de movimiento. Eso es bueno y malo, desde un punto de vista programación orientada a objetos. Al menos cuando el manejo de eventos de ratón es una responsabilidad de la HolePattern para establecer en un máximo de cada agujero (la elipse que es la visual del agujero), que se abstrae lejos para que cualquier consumidor de mi HolePattern recibirá este functioanality automactically. Sin embargo, moviéndolo al código principal de la interfaz de usuario, ahora estoy tratando con mi evento de ratón de la lona en un nivel superior. Pero eso no es todo mal. Podríamos discutir esta parte durante varios días.

El punto es, he diseñado una manera de crear un "margen de error" al momento de retirar algo en un lienzo con un ratón, y después de leer el agujero que la elipse seleccionada pertenece, y luego puedo leer el HolePattern que el agujero pertenece, y toda mi interfaz de usuario (ListView, cuadros de texto, gridview fo coordenadas) se actualizan todos en el XAML enlace existente, y el lienzo se actualiza con una llamada a un método existente para regenerar la lona.

Para ser honesto, no puedo creer que he descubierto todo esto (con su ayuda y otros también, por supuesto). Es una sensación tan cool tener la visión de este esto y ver que vienen a ser.

Salida del código principal aquí:

void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    int ClickMargin = 2;
    Point ClickedPoint = e.GetPosition(canvas1);
    Point p1 = new Point(ClickedPoint.X - ClickMargin, ClickedPoint.Y - ClickMargin);
    Point p2 = new Point(ClickedPoint.X - ClickMargin, ClickedPoint.Y + ClickMargin);
    Point p3 = new Point(ClickedPoint.X + ClickMargin, ClickedPoint.Y + ClickMargin);
    Point p4 = new Point(ClickedPoint.X + ClickMargin, ClickedPoint.Y - ClickMargin);
    var PointPickList = new Collection<Point>();
    PointPickList.Add(ClickedPoint);
    PointPickList.Add(p1);
    PointPickList.Add(p2);
    PointPickList.Add(p3);
    PointPickList.Add(p4);

    foreach (Point p in PointPickList)
    {
        HitTestResult SelectedCanvasItem = System.Windows.Media.VisualTreeHelper.HitTest(canvas1, p);
        if (SelectedCanvasItem.VisualHit.GetType() == typeof(Ellipse))
        {
            var SelectedEllipseTag = SelectedCanvasItem.VisualHit.GetValue(Ellipse.TagProperty);
            if (SelectedEllipseTag!=null &&  SelectedEllipseTag.GetType().BaseType == typeof(Hole))
            {
                Hole SelectedHole = (Hole)SelectedEllipseTag;
                SetActivePattern(SelectedHole.ParentPattern);
                SelectedHole.ParentPattern.CurrentHole = SelectedHole;

            }
        }
    }
}

Sólo Aumentar grosor del trazo de la elipse de modo que sea ajustable

por lo tanto las obras de eventos MouseLeftButtonDown Ejemplo: En la etiqueta Elipse:

Elipse  Canvas.Left = "10" Canvas.Top = "133" height = Nombre "24" = "ellipse1" width = "23" Carrera = "Rojo" MouseLeftButtonDown = información sobre herramientas "ellipse1_MouseLeftButtonDown" = "Temp Cerrar" StrokeEndLineCap = "plana" StrokeThickness = "12"

private void ellipse1_MouseLeftButtonDown (remitente del objeto, MouseButtonEventArgs e)         {             Aplicación curApp = Application.Current;             curApp.Shutdown ();         }

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top