PrimitiveShape.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using System;
  2. using System.Windows;
  3. using System.Windows.Media;
  4. using System.Windows.Shapes;
  5. using HandyControl.Data;
  6. using HandyControl.Expression.Drawing;
  7. using HandyControl.Expression.Media;
  8. namespace HandyControl.Expression.Shapes;
  9. public abstract class PrimitiveShape : Shape, IGeometrySourceParameters, IShape
  10. {
  11. private IGeometrySource _geometrySource;
  12. static PrimitiveShape()
  13. {
  14. StretchProperty.OverrideMetadata(typeof(PrimitiveShape),
  15. new DrawingPropertyMetadata(Stretch.Fill, DrawingPropertyMetadataOptions.AffectsRender));
  16. StrokeThicknessProperty.OverrideMetadata(typeof(PrimitiveShape),
  17. new DrawingPropertyMetadata(ValueBoxes.Double1Box, DrawingPropertyMetadataOptions.AffectsRender));
  18. }
  19. protected sealed override Geometry DefiningGeometry =>
  20. GeometrySource.Geometry ?? Geometry.Empty;
  21. private IGeometrySource GeometrySource => _geometrySource ?? (_geometrySource = CreateGeometrySource());
  22. Stretch IGeometrySourceParameters.Stretch => Stretch;
  23. Brush IGeometrySourceParameters.Stroke => Stroke;
  24. double IGeometrySourceParameters.StrokeThickness => StrokeThickness;
  25. public event EventHandler RenderedGeometryChanged;
  26. public void InvalidateGeometry(InvalidateGeometryReasons reasons)
  27. {
  28. if (GeometrySource.InvalidateGeometry(reasons)) InvalidateArrange();
  29. }
  30. public Thickness GeometryMargin => GeometrySource.LogicalBounds.Subtract(RenderedGeometry.Bounds);
  31. Brush IShape.Fill
  32. {
  33. get => Fill;
  34. set => Fill = value;
  35. }
  36. Stretch IShape.Stretch
  37. {
  38. get => Stretch;
  39. set => Stretch = value;
  40. }
  41. Brush IShape.Stroke
  42. {
  43. get => Stroke;
  44. set => Stroke = value;
  45. }
  46. double IShape.StrokeThickness
  47. {
  48. get => StrokeThickness;
  49. set => StrokeThickness = value;
  50. }
  51. protected override Size ArrangeOverride(Size finalSize)
  52. {
  53. if (GeometrySource.UpdateGeometry(this, finalSize.Bounds())) RealizeGeometry();
  54. base.ArrangeOverride(finalSize);
  55. return finalSize;
  56. }
  57. protected abstract IGeometrySource CreateGeometrySource();
  58. protected override Size MeasureOverride(Size availableSize) => new(base.StrokeThickness, base.StrokeThickness);
  59. private void RealizeGeometry() => RenderedGeometryChanged?.Invoke(this, EventArgs.Empty);
  60. }