WPF用户控件如何继承WPF用户控件?


92

以下WPF UserControl称为DataTypeWholeNumber起作用。

现在,我要创建一个名为DataTypeDateTimeDataTypeEmail的UserControl 。

所有这些控件将共享许多依赖项属性,因此我想将它们的通用方法放入BaseDataType中,并使每个UserControl都从该基本类型继承。

但是,当我这样做时,会出现错误:部分声明可能没有不同的基类

那么,如何使用UserControls实现继承,以便共享功能全部在基类中?

using System.Windows;
using System.Windows.Controls;

namespace TestDependencyProperty827.DataTypes
{
    public partial class DataTypeWholeNumber : BaseDataType
    {
        public DataTypeWholeNumber()
        {
            InitializeComponent();
            DataContext = this;

            //defaults
            TheWidth = 200;
        }

        public string TheLabel
        {
            get
            {
                return (string)GetValue(TheLabelProperty);
            }
            set
            {
                SetValue(TheLabelProperty, value);
            }
        }

        public static readonly DependencyProperty TheLabelProperty =
            DependencyProperty.Register("TheLabel", typeof(string), typeof(BaseDataType),
            new FrameworkPropertyMetadata());


        public string TheContent
        {
            get
            {
                return (string)GetValue(TheContentProperty);
            }
            set
            {
                SetValue(TheContentProperty, value);
            }
        }

        public static readonly DependencyProperty TheContentProperty =
            DependencyProperty.Register("TheContent", typeof(string), typeof(BaseDataType),
            new FrameworkPropertyMetadata());


        public int TheWidth
        {
            get
            {
                return (int)GetValue(TheWidthProperty);
            }
            set
            {
                SetValue(TheWidthProperty, value);
            }
        }

        public static readonly DependencyProperty TheWidthProperty =
            DependencyProperty.Register("TheWidth", typeof(int), typeof(DataTypeWholeNumber),
            new FrameworkPropertyMetadata());



    }
}

有关使用可视继承的WPF解决方法,请参阅:svetoslavsavov.blogspot.gr/2009/09/…或要在祖先中明确定义GUI,请参阅support.microsoft.com/kb/957231
George Birbilis

Answers:


130

确保已将xaml中的第一个标记更改为也继承自新的基类型

所以

<UserControl x:Class="TestDependencyProperty827.DataTypes.DataTypeWholeNumber"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    xmlns:s="clr-namespace:System;assembly=mscorlib"
    >

变成

<myTypes:BaseDataType x:Class="TestDependencyProperty827.DataTypes.DataTypeWholeNumber"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    xmlns:s="clr-namespace:System;assembly=mscorlib"
    xmlns:myTypes="clr-namespace:TestDependencyProperty827.DataTypes"
    >

因此,总结一下完整的答案,包括下面评论中的额外细节:

  • 基类不应包含xaml文件。在单个(非部分)cs文件中定义它,并将其定义为直接从Usercontrol继承。
  • 确保子类在cs代码隐藏文件和xaml的第一个标记中都继承自基类(如上所示)。

4
当我进行更改时,出现错误:“ ... DataTypes.BaseDataType不能是XAML文件的根,因为它是使用XAML定义的”,您如何摆脱这种循环引用?
爱德华·坦格

9
如果您可以仅使基类成为从UserControl继承而无需定义任何xmal的普通类型(这样就不能将部分类分为两个文件)。问题是您不能继承xmal,因此基类或子类都不需要具有xmal文件。要么使您的类成为自定义控件,而不是用户控件。这样,外观就在部分类之外定义,但是您将失去使用用户控件的便利性。
马丁·哈里斯

1
就是这样:如果将BaseDataType设置为继承UserControl的普通类,那么它将起作用。太好了,谢谢。
爱德华·坦格

@Martin您可能想要更新您的答案以反映您的评论,这才是真正的答案。
布赖恩·安德森

有没有一种方法可以使“控件库”中的元素位于继承的类之上?
Juan M. Elosegui

2
public partial class MooringConfigurator : MooringLineConfigurator
    {
        public MooringConfigurator()
        {
            InitializeComponent();
        }
    }



<dst:MooringLineConfigurator x:Class="Wave.Dashboards.Instruments.ConfiguratorViews.DST.MooringConfigurator"
    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:dst="clr-namespace:Wave.Dashboards.Instruments.ConfiguratorViews.DST"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">

    </Grid>
</dst:MooringLineConfigurator>    


0

我遇到了同样的问题,但需要让控件从抽象类继承,而设计器不支持该抽象类。解决我的问题的方法是使usercontrol从标准类(继承UserControl)和接口两者继承。这样设计师才能工作。

//the xaml
<local:EcranFiche x:Class="VLEva.SIFEval.Ecrans.UC_BatimentAgricole" 
                  xmlns:local="clr-namespace:VLEva.SIFEval.Ecrans"
                  ...>
    ...
</local:EcranFiche>

// the usercontrol code behind
public partial class UC_BatimentAgricole : EcranFiche, IEcranFiche
{
    ...
}

// the interface
public interface IEcranFiche
{
   ...
}

// base class containing common implemented methods
public class EcranFiche : UserControl
{
    ... (ex: common interface implementation)
}

0

设计者创建了部分类定义,您可以通过InitializeComponent()方法定义轻松打开它。然后只需将部分类的继承性从UserControl更改为BaseDataType(或在类定义中指定的任何类)。

之后,您将警告子类中隐藏了InitializeComponent()方法。

因此,可以使CustomControl代替UserControl作为基类,以避免在基类中进行部分定义(如一条注释中所述)。


无法从Controls.Login转换为Controls.BaseControl。
Himilou '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.