Silverlight ItemsControl. Можете ли вы удалить панель полностью с помощью шаблонов? - PullRequest
2 голосов
/ 03 февраля 2009

У меня есть DataTamplate для моего ItemsControl, который просто содержит изображение с некоторыми другими метаданными. То, что я пытаюсь сделать, - это привязать к ItemsControl и сделать так, чтобы изображения отображались с Convas.Left и Canvas.Top, которые связаны с данными, которые я предоставляю.

Я изо всех сил пытался удалить все панели из элемента управления с помощью ItemsPanelTemplate, поэтому я могу использовать Attached Properties на родительском холсте, но, похоже, вы всегда получите StackPanel по умолчанию.

У кого-нибудь есть хорошие идеи?

Спасибо, Dave

1 Ответ

6 голосов
/ 04 февраля 2009

Расположение элементов в ItemsControl контролируется с помощью свойства ItemsControl.ItemsPanel, которое имеет тип ItemsPanelTemplate. Значение по умолчанию для свойства ItemsControl.ItemsPanel действительно является экземпляром ItemsPanelTemplate, который задает StackPanel, но это полностью настраиваемо.

Пример кода ( на этой странице MSDN ), показанный под абзацем, который начинается «В следующем примере создается 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
    }
}

Это все, что вам нужно (вместе с изображениями в папке изображений) для этого конечного результата:

альтернативный текст http://www.freeimagehosting.net/uploads/bec683b75e.png

Обратите внимание, что даже несмотря на то, что Изображения находятся в ItemsControl, они располагаются в координатах, показанных путем привязки вложенных свойств Left и Top родительского Canvas к значениям координат X и Y из пользовательского свойства Location.

Для получения дополнительной информации об этом образце и настройке ItemsControl с использованием шаблонов в целом, вы можете проверить это сообщение в блоге .

...