Silverlight 4.0 Не удается создать экземпляр «CustomControl» - PullRequest
3 голосов
/ 25 июля 2011

В настоящее время я работаю над небольшим проектом, и у меня возникли некоторые проблемы с пользовательскими элементами управления silverlight.Я пытаюсь создать пользовательский ScrollViewer (который будет содержать небольшие изображения) для фотогалереи.У меня проблема в том, что Visual Studio выдает следующую ошибку:

Не удается создать экземпляр ScrollableImageViewer

Может кто-то предоставить некоторые указателиЧто может быть причиной этой ошибки, и, возможно, некоторые способы ее устранения?

Ниже приведен код XAML и C #, который я написал.

<navigation:Page x:Class="PWS.Views.Biography" 
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
       xmlns:local="clr-namespace:PWS.Controls"
       mc:Ignorable="d"
       xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
       d:DesignWidth="640" d:DesignHeight="480"
       Title="This is the biography page">
<Grid x:Name="LayoutRoot">
    <TextBlock x:Name ="tempText" FontSize="15" Foreground="Blue">this is the biography page</TextBlock>
    <local:ScrollableImageViewer x:Name= "scrollableViewer" />
</Grid>
</navigation:Page>

Мой пользовательский класс управления называется ScrollableImageViewer , а ниже вы можете увидеть его код.

namespace PWS.Controls
{
    [ContentProperty("Items")]
    public class ScrollableImageViewer : Control
    {
        public static DependencyProperty ItemsProperty = DependencyProperty.RegisterAttached("Items", typeof(IList<UIElement>), typeof(ScrollableImageViewer), new PropertyMetadata(""));

        public ScrollableImageViewer()
        {
            this.DefaultStyleKey = typeof(ScrollableImageViewer);
            this.Items = new List<UIElement>();
        }

        public IList<UIElement> Items
        {
            get { return (IList<UIElement>)GetValue(ScrollableImageViewer.ItemsProperty); }
            set { SetValue(ScrollableImageViewer.ItemsProperty, value); }
        }
    }
}

На данный момент это довольно просто и не содержит пользовательской логики для прокрутки.
Еще одна вещь, которую я должен добавить, - это файл generic.xaml, который содержит шаблон для этого элемента управления.

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:PWS.Controls"
    >
  <Style TargetType="local:ScrollableImageViewer">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="local:ScrollableImageViewer">
          <Grid Background="{TemplateBinding Background}">
            <ScrollViewer x:Name="internalScrollViewer" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                          Background="{TemplateBinding Background}"
                          VerticalScrollBarVisibility="Disabled"
                          HorizontalScrollBarVisibility="Hidden"
                          >
              <StackPanel Background="{TemplateBinding Background}" FlowDirection="LeftToRight" IsHitTestVisible="False" Children="{TemplateBinding Items}"></StackPanel>
            </ScrollViewer>
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</ResourceDictionary>

Как видно из шаблона, я хочу, чтобы мой элемент управления содержал внутренний ScrollViewer и свойство Whos Children, принадлежащее детям, должно быть привязано к свойству Items пользовательского элемента управления.

PS Я провел поиск по SO и нашел несколько вопросов, касающихся подобных проблем.Большинство из них было решено добавлением кода в конструктор, чтобы проверить, отображался ли элемент управления в режиме конструктора, но у меня это не сработало.Кажется, у меня другая проблема.

PPS Я только начинаю изучать Silverlight, поэтому, если вы видите какой-то плохой код, пожалуйста, не стесняйтесь указывать мне его.

1 Ответ

2 голосов
/ 25 июля 2011

при работе с пользовательскими элементами управления приходится сталкиваться с множеством правил.Для начала убедимся в следующем:

  1. В вашем проекте должна быть папка «themes», а внутри нее - словарь ресурсов «Generic.xaml», в котором содержится стиль вашего шаблона.
  2. КогдаОпределяя свойство зависимости, вы не можете инициализировать его значениями разных типов.Ваше свойство Items инициализируется пустой строкой (""), это начальное значение для вашего свойства внутри "PropertyMetadata".«Нуль» или «новый ...» должны помочь.

Заявив, что я предлагаю вам обойти свойство Items: дать вашей StackPanel имя, получить к нему доступ изМетод "OnApplyTemplate".Используйте временную StackPanel для хранения возможных дочерних элементов, которые могут быть добавлены до применения реального шаблона к вашему элементу управления, и, когда это действительно произойдет, передайте дочерние элементы из временной StackPanel этому элементу в шаблоне.Чтобы это работало, используйте NamedPart для вашей StackPanel.

Вот код xaml:

<Style TargetType="local:ScrollableImageViewer">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:ScrollableImageViewer">
                <Grid Background="{TemplateBinding Background}">
                    <ScrollViewer x:Name="internalScrollViewer"
                                                HorizontalAlignment="Stretch"
                                                VerticalAlignment="Stretch"
                                                Background="{TemplateBinding Background}"
                                                VerticalScrollBarVisibility="Disabled"
                                                HorizontalScrollBarVisibility="Hidden">
                        <StackPanel x:Name="myStackPanel"
                                                Background="{TemplateBinding Background}"
                                                FlowDirection="LeftToRight"
                                                IsHitTestVisible="False"></StackPanel>
                    </ScrollViewer>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Это код позади:

[TemplatePart(Name = "myStackPanel", Type = typeof(StackPanel))]
[ContentProperty("Items")]
public class ScrollableImageViewer : Control
{
    public ScrollableImageViewer()
    {
        this.DefaultStyleKey = typeof(ScrollableImageViewer);
    }

    StackPanel MyStackPanel = null;
    StackPanel TemporalSP = new StackPanel();

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        MyStackPanel = GetTemplateChild("myStackPanel") as StackPanel;

        // Pass created children before appliying the template.
        for (int i = TemporalSP.Children.Count - 1; i >= 0; i--)
        {
            UIElement OneControl = TemporalSP.Children[i];
            TemporalSP.Children.Remove(OneControl);
            MyStackPanel.Children.Add(OneControl);
        }
        TemporalSP = null;

    }

    public UIElementCollection Items
    {
        get
        {
            if (MyStackPanel != null)
                return MyStackPanel.Children;
            else
                return TemporalSP.Children;
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...