在XAML / WPF中UserControls有什么问题?

时间:2009-02-03 11:02:52

标签: wpf vb.net xaml user-controls

我遇到了让UserControl在XAML中工作的主要问题 - 我花了好几个小时试图解决所有问题,但却无处可寻,无法找到我出错的地方。
我遇到的主要问题是当我创建一个UserControl时,例如一个简单的显示一个对象不同的颜色 - 我已成功为此创建了一个属性,并且可以在设计时为这个UserControl分配颜色并且它有效 - 显示Green,红等。
但是,当我给这个UserControl一个名字,所以我可以在运行时分配这个属性我得到一个错误“无法创建类型'MyUserControl'的实例'”如果我删除用户控件的名称工作 - 我可以添加尽可能多的我想要的设计时间,他们都工作,但一旦我分配名称或x:名称,它打破了,我无法弄清楚为什么 例如,可以创建一个Label,它有一个名称,我可以在代码中引用它 - 为什么不是我自己的控件 - 无论多么简单。

我的主要问题是:

  1. 为什么要给我的UserControl一个 名称或x:名称是否停止工作?
  2. 如何使用多个 一个相同类型的UserControls 窗口?
  3. 如何访问Canvas,Label 来自内部的UserControl等 在UserControl之外?
  4. 如何实例化UserControl 运行时或在设计时代码或XAML?
  5. 我不明白为什么这些应该如此困难 - 我无法弄清楚这个问题所以如果有人可以提供帮助那么谢谢!


    这是我的UserControl的XAML和代码

    <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以消除此原因 - Code Behind如下:

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

答案 0 :(得分:2)

我不确定如果没有看到它的源代码,我可以用你的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
    }

}

该属性表示此控件需要在其模板中使用类型为Button的“PART_button”控件。然后在OnApplyTemplate方法中,您可以调用GetTemplateChild来检索所需的部分。

答案 1 :(得分:1)

1。如果添加Namex: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是一个类。除非通过模板公开,否则UserControl的XAML是私有的。因此,除非您提供方法或UserControl的使用者覆盖模板,否则它们无法控制内部。您的UserControl也是如此,它不能与其父级的内部一起玩。如果您需要紧密耦合,我建议您不要使用UserControl。

4。鉴于以下XAML:

<StackPanel x:Name="ZunePanel" />

您可以使用以下代码:

ZunePanel.Children.Add(new Draco());