Silverlight ItemsControl。你能通过模板完全拆除面板吗?

时间:2009-02-03 15:27:07

标签: silverlight data-binding templates itemscontrol

我的ItemsControl有一个DataTamplate,它只包含一个带有其他元数据的Image。我要做的是绑定到ItemsControl并使用Convas.Left和Canvas.Top显示图像,这些图像通过我给出的数据绑定。

我一直在努力通过ItemsPanelTemplate从控件中删除任何Panels,所以我可以使用父画布中的Attached Properties,但是看起来你总是默认得到一个StackPanel。

那里有人有什么好主意吗?

谢谢, 戴夫

1 个答案:

答案 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