Я пытаюсь создать приложение для создания диаграмм в C # / WPF. То, что я делаю, похоже на Microsoft Visio, хотя я не пытаюсь его клонировать. Я как бы написал этот вопрос, поскольку я кодировал, и просто включил в него все проблемы, которые у меня были, на тот случай, если кто-то сочтет это полезным. Может быть, я слишком много думал, но чувствую, что могу бросить на клавиатуре и создавать лучший код, поэтому не стесняйтесь давать любые советы по каждой детали, которую вы ловите (исключая грамматику: -))
Короче говоря:
Почему все элементы расположены в (0,0)?
Код:
public class Diagram : MultiSelector
{
public Diagram()
{
this.CanSelectMultipleItems = true;
// The canvas supports absolute positioning
FrameworkElementFactory panel = new FrameworkElementFactory(typeof(Canvas));
this.ItemsPanel = new ItemsPanelTemplate(panel);
// Tells the container where to position the items
this.ItemContainerStyle = new Style();
this.ItemContainerStyle.Setters.Add(new Setter(Canvas.LeftProperty, new Binding("X")));
this.ItemContainerStyle.Setters.Add(new Setter(Canvas.TopProperty, new Binding("Y")));
}
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
FrameworkElement contentitem = element as FrameworkElement;
Binding leftBinding = new Binding("X");
Binding topBinding = new Binding("Y");
contentitem.SetBinding(Canvas.LeftProperty, leftBinding);
contentitem.SetBinding(Canvas.TopProperty, topBinding);
base.PrepareContainerForItemOverride(element, item);
}
public class DiagramItem : ContentControl
{
private Point _location;
public DiagramItem()
{
}
static DiagramItem()
{
}
public Point Location
{
get { return _location; }
set
{
_location = value;
}
}
public double X
{
get { return _location.X; }
set
{
_location.X = value;
}
}
public double Y
{
get { return _location.Y; }
set
{
_location.Y = value;
}
}
}
//...
Хорошо, идея заключается в том, что Diagram: ItemsControl размещает свой элемент на панели Canvas в позиции, определенной в Item DiagramItem.Location. IOW, когда я изменяю свойство X в DiagramItem, диаграмма перемещает элемент по оси x.
Примечание: MultiSelector является производным от ItemsControl и Selector и используется только здесь, потому что мне нужно, чтобы отображаемый элемент был доступен для выбора.
Обратите внимание, что я бы предпочел не использовать xaml, если это возможно.
В длинну:
Экземпляр Diagram, видимый пользователем, имеет следующие требования:
- Имеет несколько DiagramItems.
- Пользователь может выбрать несколько DiagramItems.
- DiagramItems можно изменять, поворачивать и перетаскивать в любом месте диаграммы.
- Возможно перемещаться между DiagramItems с помощью клавиатуры.
У меня есть два и, возможно, три класса, относящиеся к этому вопросу.
- Диаграмма расширяет System.Windows.Controls.Primitives. MultiSelector : селектор: ItemsControl
- DiagramItem extends ContentControl или некоторый другой элемент управления
Diagram.ItemsPanel или визуальная панель, которая отображает элементы, должна быть панелью, поддерживающей абсолютное позиционирование, как Canvas .
Как мне реализовать класс, производный от MultiSelector, и какие ресурсы, на которые вы можете указать, имеют отношение к этому вопросу?
Что нужно учитывать при реализации пользовательского MultiSelector / ItemsControl?
Ресурсы:
Я нашел очень мало ресурсов, имеющих отношение к моей проблеме, но опять же я не уверен, что я должен искать. Я прочитал исходный код для ListBox и ListBoxItem с помощью Reflector, но не нашел его очень полезным.
Другие ресурсы: