![](/img/trans.png)
[英]How to bind children of ItemsControl on a custom user control to a 2D array WPF C#?
[英]How to create a custom MultiSelector / ItemsControl in WPF / C#
我正在嘗試在 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 當我更改 DiagramItem 中的 X 屬性時,圖表會在 x 軸上移動該項目。
注意: MultiSelector 派生自 ItemsControl 和 Selector,僅在此處使用,因為我需要顯示的項目是可選的。
請注意,如果可能,我不想使用 xaml。
長:
用戶看到的 Diagram 實例具有以下要求:
我基本上有兩個甚至可能三個與這個問題相關的課程。
Diagram.ItemsPanel 又名顯示項目的可視面板應該是一個支持絕對定位的面板,如Canvas 。
我應該如何實現從 MultiSelector 派生的類,以及您可以指出哪些與此問題相關的資源?
實現自定義 MultiSelector / ItemsControl 時必須考慮什么?
資源:
我發現與我的問題相關的資源很少,但我又不確定我應該尋找什么。 我已經使用 Reflector 閱讀了 ListBox 和 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;
}
}
}
神奇之處在於正確使用 Bindings,關鍵是將 contentitem 添加為Source
。 下一步顯然是處理項目的選擇,但這本身就是另一個問題。
如果有幫助,我根據我的圖形和圖表自定義控件 NetworkView 寫了一篇代碼項目文章:
http://www.codeproject.com/Articles/182683/NetworkView-A-WPF-custom-control-for-visualizing-a
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.