首先需要注意的是,当使用Canvas
面板时,面板中的每个项目都将被放置在左上角,除非指定了相对位置。这是一个带有元素的Canvas
的示例,其中一个元素靠近顶部(向下40像素,向右40像素),另一个元素位于底部(距离右侧边缘向左100像素):
<Canvas>
<Polygon Canvas.Left="40" Canvas.Top="40" ... />
<Ellipse Canvas.Right="100" Canvas.Bottom="0" ... />
</Canvas>
现在,请记住,Canvas
是 Panel
的一种类型。它的主要目的不是作为某种列表,而是更进一步定义控件(或控件)的 呈现方式。如果您希望实际呈现控件的集合/列表(枚举),那么您应该使用 ItemsControl
类型。从那里,您可以指定 ItemsSource
并自定义 ItemsPanel
(以及可能需要的 ItemTemplate
)。
其次,经常会遇到一个问题:
“如何向数据绑定的ItemsSource
添加静态元素?”,对此,答案是使用
CompositeCollection
和随后的
CollectionContainer
。在您的情况下,您有两个(2)静态项(以及更多),您希望将它们添加到您的Offices集合中。我猜这些“静态形状”实际上是楼层平面图像的替代品。
这是一个示例,如果您希望绘制您的楼层平面图,您的XAML代码将如下所示:
<ItemsControl>
<ItemsControl.Resources>
<CollectionViewSource x:Key="cvs" Source="" />
</ItemsControl.Resources>
<ItemsControl.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="" />
<!-- Static Items -->
</CompositeCollection>
</ItemsControl.ItemsSource>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas ... />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
我不确定你的Floor
集合中的每个对象都是什么,但它们不应该是任何类型的形状。它们应该是一些简单陈述有关办公室位置、颜色等信息的对象。这里是一个示例,因为你没有提供项目集合的组成部分:
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; }
}
在这里,您需要使用一个 DataTemplate
来将对象(模型/视图模型)转换为视图上应该呈现的样子:
<ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Polygon Points="" Color="AliceBlue" ... />
<DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
当然,如果你希望从你的集合
Offices
中拥有每个项目的多个表示方式,则需要利用
DataTemplateSelector
(将设置为
ItemsControl.ItemTemplateSelector
属性)从一组
DataTemplate
中进行选择。这里有一个很好的答案/参考:
https://stackoverflow.com/a/17558178/347172。
最后,还有一点需要注意...保持一切按比例缩放,并将您的点作为
double
类型。个人建议使用0-1或0-100的比例尺。只要所有点和静态项都在这个范围内,您就可以将
ItemsControl
拉伸到任意高度/宽度,里面的所有内容也会相应地调整并匹配得很好。
更新: 已经过了一段时间,我忘记了
CompositeCollection
类不是
FrameworkElement
类型,因此它没有DataContext。如果您想要绑定其中一个集合的数据,请指定一个具有所需DataContext的
FrameworkElement
引用:
<CollectionContainer Collection="{Binding DataContext.Offices, Source={x:Reference someControl}}"/>
更新2:在网上挖掘了一段时间后,我找到了一个更好的方法来允许数据绑定与
CompositeCollection
一起使用。上面的答案部分已经更新以考虑使用
CollectionViewSource
来创建一个绑定到集合的资源。这比使用
x:Reference
要好得多。希望能有所帮助。
Canvas
位于一个与我的视图模型松散耦合的UserControl
中)。 - Elliott DarfinkFloor
集合中有哪些类型的对象? - myermian