如何创建一个自定义MultiSelector/获取定在WPF/C#
-
22-07-2019 - |
题
我试图建立一个绘图应用程序在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;
}
}
}
//...
Ok,这样的想法是 图:获取定 地方,其项目上的画面在定义的位置在该项目DiagramItem.位置。IOW当我改变X的财产在一个DiagramItem图移该项目在x轴上。
注: MultiSelector是来自获取定和选择,并且只用于这里因为我需要显示项目是可选择的。
请注意,我不喜欢使用xaml如果可能的。
在长:
图例如通过用户拥有这些要求:
- 有多个DiagramItems.
- 用户可以选择多个DiagramItems.
- DiagramItems可以调整、旋转和拖上的任何地方的图。
- 可能导航之间DiagramItems使用键盘。
我基本上有两个,可能是三类有关这个问题。
- 图 延伸系统。窗户。控制。元。MultiSelector :选择:获取定
- DiagramItem 延伸 型 或者一些其他的控制
图。ItemsPanel aka些面板,显示的项目应该是一个小组,支持绝对的定位,喜欢的 画布.
我应该怎样实现一类源自MultiSelector什么资源可以,你在哪一点有关这个问题?
什么一个有时要考虑实施一个自定义MultiSelector/获取定?
资源:
我已经找到很少的资源有关我的问题,但后来又来了我不知道什么我应该是寻找。我读的源代码列表框并ListBoxItem使用反射器,但没有发现它很有用的。
其他资源:
解决方案
好的,显然这可以很容易地通过利用绑定和属性的框架。
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("XProperty");
leftBinding.Source = contentitem;
Binding topBinding = new Binding("YProperty");
topBinding.Source = contentitem;
contentitem.SetBinding(Canvas.LeftProperty, leftBinding);
contentitem.SetBinding(Canvas.TopProperty, topBinding);
base.PrepareContainerForItemOverride(element, item);
}
public class DiagramItem : ContentControl
{
public static readonly DependencyProperty XProperty;
public static readonly DependencyProperty YProperty;
public static readonly RoutedEvent SelectedEvent;
public static readonly RoutedEvent UnselectedEvent;
public static readonly DependencyProperty IsSelectedProperty;
public DiagramItem()
{
}
static DiagramItem()
{
XProperty = DependencyProperty.Register("XProperty", typeof(Double), typeof(DiagramItem));
YProperty = DependencyProperty.Register("YProperty", typeof(Double), typeof(DiagramItem));
SelectedEvent = MultiSelector.SelectedEvent.AddOwner(typeof(DiagramItem));
UnselectedEvent = MultiSelector.SelectedEvent.AddOwner(typeof(DiagramItem));
IsSelectedProperty = MultiSelector.IsSelectedProperty.AddOwner(typeof(DiagramItem));
}
public Double X
{
get
{
return (Double)this.GetValue(XProperty);
}
set
{
this.SetValue(XProperty, value);
}
}
public Double Y
{
get
{
return (Double)this.GetValue(YProperty);
}
set
{
this.SetValue(YProperty, value);
}
}
public Point Location
{
get
{
return new Point(X, Y);
}
set
{
this.X = value.X;
this.Y = value.Y;
}
}
}
魔法是在适当的使用情况的Bingings,关键是要加contentitem为源。下一步骤显然是要处理该项目的选择,但这是另一个问题上它自己的。
其他提示
如果它是任何帮助,我写了一个项目文的基础上,我绘图和图表绘制定控制称为NetworkView:
http://www.codeproject.com/Articles/182683/NetworkView-A-WPF-custom-control-for-visualizing-a