В чем проблема с UserControls в XAML / WPF? - PullRequest
2 голосов
/ 03 февраля 2009

У меня были серьезные проблемы с тем, чтобы заставить UserControls работать в XAML - я потратил часы, пытаясь выяснить все проблемы, но не нашел нигде и не могу найти, где я иду не так.
Основная проблема, с которой я сталкиваюсь, - это когда я создаю пользовательский элемент управления, например, простой, который показывает объект разными цветами - я успешно создал свойство для этого и могу назначить цвета этому элементу управления во время разработки, и он работает - показывает зеленый, Красный и т. Д.
Однако, когда я даю этому UserControl имя, чтобы я мог назначить это свойство во время выполнения, я получаю ошибку «Не удалось создать экземпляр типа« MyUserControl »», если я удаляю имя, с которым работает пользовательский элемент управления - я могу добавить столько, сколько захочу ». Время разработки, и все они работают, но как только я присваиваю Имя или x: Имя, оно ломается, и я не могу понять, почему.
Например, можно создать ярлык, и у него есть имя, на которое я могу сослаться в коде - почему бы не мой собственный элемент управления - независимо от того, насколько он прост.

Мои основные проблемы:

  1. Почему предоставление моего UserControl Имя или х: имя остановить его работать?
  2. Как использовать несколько UserControls того же типа на Окно
  3. Как получить доступ к Canvas, Label и т. д. UserControl изнутри или вне UserControl?
  4. Как создать экземпляр UserControl на время выполнения или во время разработки в коде или XAML?

Я не понимаю, почему это должно быть так сложно - я не могу разобраться в этом вопросе, поэтому, пожалуйста, если кто-то может помочь, тогда спасибо!


Вот XAML и код для моего UserControl

<UserControl x:Class="Device.Draco"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="20" Height="36" x:Name="Icon">
    <Canvas Width="20" Height="36" HorizontalAlignment="Left" VerticalAlignment="Top">
        <Rectangle Height="36" Width="20" Fill="{Binding ElementName=Icon, Path=ZuneColour}" Canvas.Left="0" Canvas.Top="0" RadiusX="1" RadiusY="1">
            <Rectangle.BitmapEffect><OuterGlowBitmapEffect GlowColor="Black" GlowSize="2" /></Rectangle.BitmapEffect>
        </Rectangle>
        <Rectangle Canvas.Left="1" Canvas.Top="1" Height="24" Stroke="#191616" Width="18">
            <Rectangle.Fill>
                <LinearGradientBrush>
                    <GradientStop Offset="1" Color="#231F20"/>
                    <GradientStop Offset="0" Color="#524F4F"/>
                    <LinearGradientBrush.Transform>
                        <RotateTransform Angle="68" CenterX="0.5" CenterY="0.5"/>
                    </LinearGradientBrush.Transform>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>
        <Rectangle Canvas.Left="5.5" Canvas.Top="25" Height="9" Width="9" RadiusX="3" RadiusY="3">
            <Rectangle.Fill>
                <LinearGradientBrush>
                    <GradientStop Offset="0" Color="#66000000"/>
                    <GradientStop Offset="1" Color="#22000000"/>
                </LinearGradientBrush>
            </Rectangle.Fill>
            <Rectangle.Stroke>
                <LinearGradientBrush>
                    <GradientStop Offset="0" Color="#66FFFFFF"/>
                    <GradientStop Offset="1" Color="#22FFFFFF"/>
                </LinearGradientBrush>
            </Rectangle.Stroke>
        </Rectangle>
    </Canvas>

Это код для UserControl - все стили добавлены и заполняются как простой XAML, чтобы устранить эту причину как причину - код сзади приведен ниже:

Namespace Device
    Partial Public Class Draco
        Inherits System.Windows.Controls.UserControl
        Public Shared ZuneColorProperty As DependencyProperty = _
        DependencyProperty.Register("ZuneColour", GetType(Brush), GetType(Device.Draco))
        Public Property ZuneColour() As Brush
            Get
                Return GetValue(ZuneColorProperty)
            End Get
            Set(ByVal Value As Brush)
                SetValue(ZuneColorProperty, Value)
            End Set
        End Property
    End Class
End Namespace

Вот пример того, как я использую его в настоящее время

<Window x:Class="Demo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ui="clr-namespace:ZuneCards.Device"
    Title="Demo" Height="300" Width="300" Name="Window1">
    <Grid>
        <ui:Draco ZuneColour="Pink" HorizontalAlignment="Right" Margin="0,113,81,113" Width="20"></ui:Draco>
    </Grid>
</Window>

Ответы [ 2 ]

2 голосов
/ 03 февраля 2009

Я не уверен, что смогу решить ваши конкретные проблемы с вашим UserControl, не увидев исходный код для него.

Однако я могу ответить на часть 3. Если вы присваиваете части шаблона элемента управления имя, вы можете извлечь эту часть из кода элемента управления. Оттуда вы можете вернуть его публично, если это необходимо.

<ControlTemplate TargetType="{x:Type l:MyUserControl}">
    <Button x:Name="PART_button">My Button</Button>
</ControlTemplate>

[TemplatePart(Name = "PART_button", Type = typeof(Button))]
public class MyUserControl:UserControl
{

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        Button button = (Button)base.GetTemplateChild("PART_button");

        // do something with the button control
    }

}

Атрибут говорит, что этот элемент управления нуждается в элементе управления "PART_button" типа Button в своем шаблоне. Затем в методе OnApplyTemplate вы можете вызвать GetTemplateChild, чтобы получить нужную часть.

1 голос
/ 03 февраля 2009

1. Возможно, что-то не так, если добавление Name или x:Name приводит к сбою UserControl. Кроме того, используйте x:Name сверх Name.

2. Следующий код будет использовать несколько элементов управления:

<WrapPanel>
    <ui:Draco ZuneColour="Pink" Width="20" />
    <ui:Draco ZuneColour="Red" Width="20" />
    <ui:Draco ZuneColour="Orange" Width="20" />
</WrapPanel>

3. UserControl - это класс. XAML для UserControl является закрытым, если не предоставляется через шаблоны. Поэтому, если вы не предоставите методы или потребитель UserControl не переопределит шаблон, они не смогут управлять внутренностями. То же самое касается вашего UserControl, он не может играть с внутренностями своего родителя. Если вам нужна такая тесная связь, я предлагаю вам не использовать UserControl.

4. Учитывая следующее XAML:

<StackPanel x:Name="ZunePanel" />

Вы можете использовать следующий код:

ZunePanel.Children.Add(new Draco());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...