【问题标题】:Is it (not) possible to use a customized WPF control just like its base class (StackPanel in this case) in XAML?是否可以(不能)在 XAML 中使用自定义的 WPF 控件,就像它的基类(在本例中为 StackPanel)一样?
【发布时间】:2018-10-11 13:05:33
【问题描述】:

我想创建一个基于 StackPanel 的自定义控件,因为我需要向派生类添加一些代码。

我在 Visual Studio 中创建了自定义控件。

当我想在 XAML 中使用自定义控件时,我会遇到各种错误。

我是 WPF 新手。

是否可以(不能)使用自定义的 WPF 控件,就像其在 XAML 中的基类(本例中为 StackPanel)一样?

c#代码是

namespace MyNameSpace
{
    public class AbstractForm : StackPanel
    {
        static AbstractForm()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(AbstractForm), new FrameworkPropertyMetadata(typeof(AbstractForm)));
        }
        protected override Size MeasureOverride(Size constraint)
        {
            return base.MeasureOverride(constraint);
        }
        protected override Size ArrangeOverride(Size arrangeBounds)
        {
            return base.ArrangeOverride(arrangeBounds);
        }
        // more code
    }
}

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:MyNameSpace">

    <Style TargetType="{x:Type local:AbstractForm}"
        BasedOn = "{StaticResource {x:Type StackPanel}}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:AbstractForm}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

然后我尝试在 MainWindow.xaml 中像 StackPanel 一样使用“AbstractForm”:

<Window x:Name="MyApp" x:Class="MyNameSpace.MainWindow"
        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:control="clr-namespace:MyNameSpace"
        mc:Ignorable="d"
        Title="MyApp" BorderBrush="{DynamicResource {x:Static SystemColors.ActiveCaptionTextBrushKey}}">
    <StackPanel x:Name="MyAppUI" Orientation = "vertical" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top">
        <control:AbstractForm x:Name="HeaderArea" Orientation = "horizontal" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top">
            <Image x:Name="appImage" HorizontalAlignment="Left" VerticalAlignment="Top" Source = "AppImage.gif"/>
            <StackPanel Orientation = "vertical" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top">
                <!-- more content -->
            </StackPanel>
        </control:AbstractForm>
        <!-- more content -->
    </StackPanel>
</Window>

运行我的应用程序时,我看到以下错误 (试图从德语重新翻译):

  • 在“AbstractForm”中找不到“方向”属性
  • 元素“方向”无法识别或无法访问
  • XML 命名空间“clr-namespace:MyNameSpace”中不包含属性“方向”。行...列...
  • 不能向“AbstractForm”类型的对象添加任何内容(即&lt;Image 和另一个&lt;StackPanel

【问题讨论】:

  • 看看:stackoverflow.com/questions/269106/…。您不能继承 Xaml 部分,只能继承代码隐藏
  • 也许您可以创建一个自定义控件并将堆栈面板添加到 xaml?然后在c#代码中扩展StackPanel
  • 您不能为 StackPanel 定义控件模板 (ControlTemplate),因为它不是控件(不是从 System.Window.Controls.Control 类派生的)。您可以创建一个自定义/用户控件,将 StackPanel 作为子控件。
  • 这不是初学者级别的任务。您可能会发现此页面,但它的链接很有趣。 wpftutorial.net/CustomLayoutPanel.html

标签: c# wpf xaml


【解决方案1】:

StackPanel 不是从 Control 派生的,因此没有 Template 属性。因此 ResourceDictionary 无法编译。

从默认样式中移除 Setter,然后重新构建您的项目。

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyNameSpace">

    <Style TargetType="{x:Type local:AbstractForm}"
           BasedOn="{StaticResource {x:Type StackPanel}}">
    </Style>
</ResourceDictionary>

如果您的 AbstractForm 类需要一个默认样式也是值得怀疑的。

如果没有,只需删除整个 Generic.xaml 文件和覆盖 DefaultStyleKey 属性默认值的静态构造函数。换句话说,只需创建一个从 StackPanel 派生的类。

【讨论】:

  • 我从 Generic.xaml 中删除了 AbstractForm 的
  • 我接受了答案,但显然我没有适当的投票特权来投票。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-04
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
  • 1970-01-01
  • 2023-03-22
相关资源
最近更新 更多