2

我的 ItemsControl 有一个 DataTamplate,它只包含一个带有其他元数据的图像。我想要做的是绑定到 ItemsControl 并让图像与通过我提供的数据绑定的 Convas.Left 和 Canvas.Top 一起显示。

我一直在尽力通过 ItemsPanelTemplate 从控件中删除任何面板,因此我可以使用父画布中的附加属性,但似乎默认情况下您总是会得到一个 StackPanel。

有人有什么好主意吗?

谢谢,戴夫

4

1 回答 1

6

ItemsControl 中项目的布局通过 ItemsControl.ItemsPanel 属性进行控制,该属性的类型为 ItemsPanelTemplate。ItemsControl.ItemsPanel 属性的默认值确实是 ItemsPanelTemplate 的一个实例,它指定了一个 StackPanel,但这是完全可定制的。

代码示例(在此 MSDN 页面上)显示在“以下示例创建一个 ItemsControl”的段落下方。对于理解 ItemsControl.Template、ItemsControl.ItemsPanel 和 ItemsControl.ItemTemplate 属性的用途非常有用。

有几种方法可以实现您在问题第一段第二句中描述的内容。这是一个完整的例子:

页面.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>

国家.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
    }
}

这就是最终结果所需要的(以及图像文件夹中的图像):

替代文字 http://www.freeimagehosting.net/uploads/bec683b75e.png

请注意,即使图像位于 ItemsControl 中,它们也会定位在通过将其父 Canvas 的 Left 和 Top 附加属性绑定到自定义 Location 属性的 X 和 Y 坐标值来显示的坐标处。

有关此示例和使用模板自定义 ItemsControl 的更多信息,您可以查看此博客文章

于 2009-02-04T09:42:03.993 回答