我的ItemsControl有一个DataTamplate,它只包含一个带有其他元数据的Image。我要做的是绑定到ItemsControl并使用Convas.Left和Canvas.Top显示图像,这些图像通过我给出的数据绑定。
我一直在努力通过ItemsPanelTemplate从控件中删除任何Panels,所以我可以使用父画布中的Attached Properties,但是看起来你总是默认得到一个StackPanel。
那里有人有什么好主意吗?
谢谢, 戴夫
答案 0 :(得分:6)
ItemsControl中项目的布局是通过ItemsConnel.ItemsPanel属性控制的,该属性的类型为ItemsPanelTemplate。 ItemsControl.ItemsPanel属性的默认值确实是ItemsPanelTemplate的一个实例,它指定了一个StackPanel,但这是完全可自定义的。
代码示例(on this MSDN page)显示在开头的段落下面“以下示例创建ItemsControl”。在理解ItemsControl.Template,ItemsControl.ItemsPanel和ItemsControl.ItemTemplate属性的用途方面非常有用。
有几种方法可以实现您在问题第一段第二句中所描述的内容。这是一个完整的例子:
Page.xaml:
<UserControl x:Class="ItemsControlImages.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:app="clr-namespace:ItemsControlImages">
<UserControl.Resources>
<DataTemplate x:Key="CountryTemplate">
<Canvas>
<Image Canvas.Top="{Binding Location.Y}"
Canvas.Left="{Binding Location.X}"
Source="{Binding FlagImage}" />
<StackPanel Canvas.Top="{Binding Location.Y}"
Canvas.Left="{Binding Location.X}">
<TextBlock Text="{Binding Title}" />
<TextBlock Text="{Binding Location}" />
<StackPanel.RenderTransform>
<TranslateTransform Y="-32.0" />
</StackPanel.RenderTransform>
</StackPanel>
</Canvas>
</DataTemplate>
</UserControl.Resources>
<Canvas x:Name="LayoutRoot">
<Canvas.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFB2C6D5"/>
<GradientStop Color="#FF1483D9" Offset="1"/>
</LinearGradientBrush>
</Canvas.Background>
<ItemsControl ItemTemplate="{StaticResource CountryTemplate}">
<app:Country Title="Argentina" Location="56,218" FlagImage="Images/ARG.png" />
<app:Country Title="China" Location="368,66" FlagImage="Images/CHN.png" />
<app:Country Title="Ireland" Location="192,90" FlagImage="Images/IRE.png" />
<app:Country Title="New Zealand" Location="404,225" FlagImage="Images/NZ.png" />
<app:Country Title="United States" Location="40,80" FlagImage="Images/USA.png" />
</ItemsControl>
</Canvas>
</UserControl>
Country.cs:
using System.ComponentModel;
using System.Windows;
namespace ItemsControlImages
{
public class Country : INotifyPropertyChanged
{
private string title;
private string flagImage;
private Point location;
public string Title
{
get
{
return this.title;
}
set
{
if ((object.ReferenceEquals(this.title, value) != true))
{
this.title = value;
this.RaisePropertyChanged("Title");
}
}
}
public string FlagImage
{
get
{
return this.flagImage;
}
set
{
if ((object.ReferenceEquals(this.flagImage, value) != true))
{
this.flagImage = value;
this.RaisePropertyChanged("FlagImage");
}
}
}
public Point Location
{
get
{
return this.location;
}
set
{
if ((this.location.Equals(value) != true))
{
this.location = value;
this.RaisePropertyChanged("Location");
}
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
这就是你需要的(以及Images文件夹中的图像)以获得最终结果:
alt text http://www.freeimagehosting.net/uploads/bec683b75e.png
注意即使图像位于ItemsControl中,它们也会通过将其父Canvas的Left和Top附加属性绑定到自定义Location属性的X和Y坐标值来显示在所示坐标处。
有关此示例的详细信息以及使用模板自定义ItemsControl,您可以查看this blog post。