嗯,这里有几点需要注意。首先,在使用Canvas
面板时,面板中的每个项目都将放置在左上角,除非指定了相对位置。这是一个Canvas
带有元素的示例,一个位于顶部附近(向下 40 像素,向右 40 像素),另一个位于底部(距右边缘左侧 100 像素):
<Canvas>
<Polygon Canvas.Left="40" Canvas.Top="40" ... />
<Ellipse Canvas.Right="100" Canvas.Bottom="0" ... />
</Canvas>
现在,请记住 aCanvas
是 的一种Panel
。它的主要目的不是成为某种列表,而是进一步定义控件(或控件)的呈现方式。如果您希望实际呈现控件的集合/列表(枚举),那么您应该使用. 从那里,您可以指定和自定义(以及,这可能是必要的)。ItemsControl
ItemsSource
ItemsPanel
ItemTemplate
其次,这经常出现,是“如何将静态元素添加到ItemsSource
数据绑定?” , 答案是使用CompositeCollection
, 和后续CollectionContainer
. 在您的情况下,您有两 (2) 个静态项目(以及更多)希望添加到您的 Offices 集合中。我猜这些“静态形状”实际上是平面图图像的替代品。
如果您希望绘制平面图,下面是 XAML 的示例:
<ItemsControl>
<ItemsControl.Resources>
<CollectionViewSource x:Key="cvs" Source="{Binding Floors}" />
</ItemsControl.Resources>
<ItemsControl.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource cvs}" />
<!-- Static Items -->
</CompositeCollection>
</ItemsControl.ItemsSource>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas ... />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
我不确定您Floor
收藏中的每个对象是什么,但它们根本不应该是任何类型的形状。它们应该是一个简单地说明有关办公室位置、颜色等信息的对象。这是我猜测的一个示例,因为您没有提供项目集合的组成部分:
// This can (and should) implement INotifyPropertyChanged
public class OfficeViewModel
{
public string EmployeeName { get; private set; }
public ReadOnlyObservableCollection<Point> Points { get; private set; }
...
}
public class Point
{
public double X { get; set; }
public double Y { get; set; }
}
从这里您将使用 aDataTemplate
将对象(模型/视图模型)转换为您视图上的样子:
<ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Polygon Points="{Binding Points}" Color="AliceBlue" ... />
<DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
当然,如果您希望从集合中获得每个项目的多个表示形式Offices
,那么您将不得不利用DataTemplateSelector
(将设置为ItemsControl.ItemTemplateSelector
属性)从一组DataTemplate
s 中进行选择。这是一个很好的答案/参考:https ://stackoverflow.com/a/17558178/347172
最后,最后一点...保持一切规模和你的观点为double
. 就我个人而言,我总是使用 0-1 或 0-100 的比例。只要您的所有点和静态项目都在该范围内,您就可以将您的点伸展ItemsControl
到任何高度/宽度,并且内部的所有内容也将调整并匹配得很好。
更新:已经有一段时间了,我忘记了这个CompositeCollection
类不是 的类型FrameworkElement
,所以它没有 DataContext。如果要对其中一个集合进行数据绑定,则必须使用FrameworkElement
所需的 DataContext 指定对 a 的引用:
<CollectionContainer Collection="{Binding DataContext.Offices, Source={x:Reference someControl}}"/>
更新2:在网上挖掘了一段时间后,我找到了一种更好的方法来允许数据绑定与CompositeCollection
,上面的答案部分已更新以通过使用CollectionViewSource
创建绑定到集合的资源来解决此问题。这比使用x:Reference
. 希望有帮助。