2011-03-24 17 views
14

Tengo un ItemsControl que dibuja miles de elipses en un diagrama de dispersión en un lienzo. Mi problema es si posiciono una elipse en las coordenadas (4, 6) con una altura y un ancho de 10. La parte superior izquierda de la elipse está en (4, 6) y la forma se extiende hacia abajo y hacia la derecha.WPF Center Ellipse en X, Y

Lo que me gustaría hacer es centrar las elipses en coordenadas específicas en XAML sin tener que usar ajustes en mi capa de ViewModel.

Aquí está el control de usuario de trabajo que tiene mi gráfico:

<Grid> 
     <ItemsControl ItemsSource="{Binding State.Data}"> 

      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <Canvas ClipToBounds="False"/> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 

      <ItemsControl.ItemContainerStyle> 
       <Style TargetType="ContentPresenter"> 
        <Setter Property="Canvas.Left" Value="{Binding Path=X}" /> 
        <Setter Property="Canvas.Top" Value="{Binding Path=Y}" /> 
       </Style> 
      </ItemsControl.ItemContainerStyle> 

      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <Ellipse Fill="Red" VerticalAlignment="Center" HorizontalAlignment="Center" Width="10" Height="20"/> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 

     </ItemsControl> 
    </Grid> 

Esto funciona muy bien a excepción de las elipses no centrados. ¿Algunas ideas?

Respuesta

2

Sugiero que usted cambie su ViewModel y nombre las propiedades Izquierda y Superior, por lo que está claro lo que significa. Si también necesita los valores X e Y, simplemente déjelos. Sugiero esto, porque X e Y pueden significar cosas diferentes, dependiendo de la forma que estés dibujando.

+0

Si hago eso, entonces tendré que conocer el radio de la Elipse para poder centrarlo correctamente donde yo quiero. Realmente me gustaría evitar hacer eso para poder jugar con mi Vista y mantener esas elipsis centradas. – bufferz

+0

@bufferz: No te entiendo. ¿Cómo crees que puedes lograr esto sin conocer los parámetros exactos de tu forma? Como señaló djacobson, no necesitas saber el radio, cuando tienes ancho y alto. –

+0

Esperaba que esto se pudiera hacer automáticamente, sin que tuviera que conocer el radio (o el ancho/alto) de la elipse. Algo así como cómo se puede centrar un TextBlock o etiqueta sin saber la longitud de su contenido. – bufferz

2

Dado que las propiedades Canvas.Left/derecha/arriba/abajo medir la distancia entre los lados de la tela y las partes asociadas de su elipse, la única manera de utilizarlos para controlar el lugar en el centro de las tierras elipse es para acomodar su altura y ancho en ViewModel.

En otras palabras, sin embargo, que haya determinado que el centro de la elipse debe aterrizar en (4,6), y que debería tener altura/anchura = 10, los X y Y propiedades expuestas por el modelo de vista debe tener los valores 4 - 10 y 6 - 10 (es decir, (-6, -4)), que serían los valores resultantes de Canvas.Left y Canvas.Top.

Actualización: Después de pensar en esto un poco más, se me ocurrió una alternativa. Como advertencia, no he probado esto. Pero si acaba de utilizar su solución actual y diseñó las elipses de modo que su Margin (o al menos sus márgenes superior/izquierdo) fueran igual a -1 * Height (or Width), eso (creo) aterrizaría en el centro en las coordenadas dadas por X y Y .. . Merece un intento. :)

+0

Dang, esperaba que hubiera una solución de marcado simple. Gracias – bufferz

+0

@bufferz Ver mi actualización. Pude haber encontrado algo (pero no lo he probado) –

8

No es totalmente automático, pero esta solución, al menos, mantener la lógica centrado dentro de la vista y no enturbiar su modelo

<Ellipse Fill="Red" Width="10" Height="20"> 
    <Ellipse.RenderTransform> 
    <TranslateTransform X="-5" Y="-10" /> 
    </Ellipse.RenderTransform> 
</Ellipse> 
+0

¡Gracias! Esto me ayudó. –

12

Puede utilizar EllipseGeometry para lograr esto.

El XAML:

<Path Stroke="Black" StrokeThickness="3" Fill="Red" > 
    <Path.Data> 
     <EllipseGeometry 
      Center="{Binding Path=CenterPoint}" 
      RadiusX="5" 
      RadiusY="10" /> 
    </Path.Data> 
</Path> 

la vista del modelo:

public Point CenterPoint { get; set;} 

No se puede tomar el crédito, me encontré con este here.

+0

Encuadernación EllipseGeometry.Center no funciona cuando lo intento. Al menos no desde dentro de una plantilla de control. La elipse simplemente va a 0,0 y no se mueve cuando se cambia el punto. – Nick

+0

@Nick, suena como un problema vinculante en lugar de algo inherente a 'EllipseGeometry' o' ControlTemplate'. En el ejemplo anterior, busco la salida del programa para "CenterPoint" para ver si hay algún error de encuadernación. De lo contrario, parece que sería una buena pregunta por sí mismo. Todo lo que puedo decir sobre esto es que funciona bien sin ataduras. –

+0

He agregado una nueva pregunta para esto. En caso de que esté interesado: https://stackoverflow.com/questions/24534148/how-can-i-bind-to-the-center-property-of-an-ellipsegeometry – Nick