Создание треугольника с привязкой к данным? - PullRequest
2 голосов
/ 08 ноября 2011

У меня есть требование создать несколько фигур на основе предоставленного размера (все они имеют одинаковую высоту / ширину), и их размеры должны быть привязаны к данным для данного предоставленного свойства в тексте данных.

Большинствоформы просты: круг (эллипс с привязкой к высоте / ширине), квадрат (прямоугольник с привязкой к высоте / ширине), ромб (такой же, как квадрат, затем используйте RotateTransform), + (две строки), X (две строки).

Но я пытаюсь понять, как сделать это для треугольника, и я не могу понять это.Это должен быть заполненный объект, поэтому я не могу просто сделать это с тремя строками.

Но все способы, которые я видел (w / a Path или Polygon), заканчиваются тем, что взяли Point объектов (StartPoint, EndPoint и т. Д.).И вы не можете привязать значения X или Y объекта Point.

Я что-то упустил?Или мне нужно написать свою собственную форму или что-то в этом роде?

Редактировать: Чтобы добавить немного ясности ... тип треугольника, который я создаю, на самом деле не имеет значения.Это может быть равносторонний или равнобедренный.Я нацелился на равнобедренный, чтобы у него была база с шириной границы данных, а верхний «кончик» треугольника будет в средней точке ширины границы данных и при Y = 0.Это была просто оптимизация ради простоты

Ответы [ 2 ]

2 голосов
/ 09 ноября 2011

Класс поведения:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Shapes;
using System.Windows.Media;

namespace WpfApplication1
{
    public enum ShapeType
    {
        Rectangle,
        Isosceles,
        Ellipse,
        Dice,
        Hexagon
    }

    public class PathControl
    {
        public static readonly DependencyProperty ShapeTypeProperty =
            DependencyProperty.RegisterAttached("ShapeType",
            typeof(ShapeType?),
            typeof(DependencyObject),
            new PropertyMetadata(null, 
                new PropertyChangedCallback((sender, args) => 
                { 
                    Path path = sender as Path;
                    ShapeType? shapeType = (ShapeType?)args.NewValue;

                    //todo: use a WeakEvent
                    path.SizeChanged += 
                        (pathSender, pathArgs) => 
                        {
                            PathControl.InvalidatePath((Path)sender, shapeType);
                        };

                })));


        private static void InvalidatePath(Path path, ShapeType? shapeType)
        {
            if (path != null
                && shapeType.HasValue)
            {
                string source = null;

                double netWidth = path.Width - 2 * path.StrokeThickness,
                       netHeight = path.Height - 2 * path.StrokeThickness;

                if (shapeType == ShapeType.Rectangle)
                {
                    source = string.Format("M0,0 h{0} v{1} h-{0} z",
                        new object[2]
                        {
                            netWidth,
                            netHeight
                        });
                }
                else if (shapeType == ShapeType.Isosceles)
                {
                    source = string.Format("M0,{1} l{0},-{1} {0},{1} z",
                        new object[2]
                        {
                            netWidth / 2,
                            netHeight
                        });
                }
                else
                {
                    throw new NotImplementedException(shapeType.ToString());
                }

                path.Data = Geometry.Parse(source);
            }
        }

        public static void SetShapeType(DependencyObject o, ShapeType e)
        {
            o.SetValue(PathControl.ShapeTypeProperty, e);
        }

        public static ShapeType? GetShapeType(DependencyObject o)
        {
            return (ShapeType)o.GetValue(PathControl.ShapeTypeProperty);
        }
    }
}

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:local="clr-namespace:WpfApplication1">
    <Grid>
        <Path Width="100" Height="100" Stroke="Green" StrokeThickness="2" Fill="Yellow"
              local:PathControl.ShapeType="Isosceles">
            <Path.RenderTransform>
                <RotateTransform Angle="90"></RotateTransform>
            </Path.RenderTransform>
        </Path>
    </Grid>
</Window>
2 голосов
/ 08 ноября 2011

Привязка к точкам является лучшим / единственным способом.Свойства X и X точки не могут быть связаны, потому что они не вызывают событие PropertyChanged.Point - это структура, и структуры должны быть доступны только для чтения.

Класс PointCollection вызывает правильные события, чтобы вы могли связываться с ними.Это позволяет вам манипулировать треугольниками, изменяя набор точек путем замены точек.Не меняйте точку, а заменяйте их, чтобы вызвать правильные события.

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