Làm thế nào để một UserControl WPF kế thừa một WPF UserControl?


92

WPF UserControl sau được gọi là DataTypeWholeNumber hoạt động.

Bây giờ tôi muốn tạo một UserControl có tên là DataTypeDateTimeDataTypeEmail , v.v.

Nhiều Thuộc tính Phụ thuộc sẽ được chia sẻ bởi tất cả các điều khiển này và do đó tôi muốn đặt các phương thức chung của chúng vào một BaseDataType và để mỗi UserControl này kế thừa từ loại cơ sở này.

Tuy nhiên, khi tôi làm điều đó, tôi gặp lỗi: Khai báo một phần có thể không có các lớp cơ sở khác nhau .

Vì vậy, làm thế nào tôi có thể thực hiện kế thừa với UserControls để chức năng được chia sẻ là tất cả trong lớp cơ sở?

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());



    }
}

để biết giải pháp WPF với kế thừa trực quan, hãy xem: svetoslavsavov.blogspot.gr/2009/09/… hoặc để xác định rõ ràng GUI trong tổ tiên, hãy xem support.microsoft.com/kb/957231
George Birbilis

Câu trả lời:


130

Đảm bảo rằng bạn đã thay đổi thẻ đầu tiên trong xaml để cũng kế thừa từ basetype mới của bạn

Vì thế

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

trở thành

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

Vì vậy, để tóm tắt câu trả lời đầy đủ bao gồm các chi tiết bổ sung từ các bình luận bên dưới:

  • Lớp cơ sở không được bao gồm tệp xaml. Xác định nó trong một tệp cs (không phải một phần) và xác định nó để kế thừa trực tiếp từ Usercontrol.
  • Đảm bảo rằng lớp con kế thừa từ lớp cơ sở cả trong tệp mã phía sau cs và trong thẻ đầu tiên của xaml (như được hiển thị ở trên).

4
khi tôi thực hiện thay đổi đó, tôi gặp lỗi: "... DataTypes.BaseDataType không thể là gốc của tệp XAML vì nó được định nghĩa bằng XAML", làm cách nào để thoát khỏi tham chiếu vòng này?
Edward Tanguay

9
Nếu bạn chỉ có thể làm cho lớp cơ sở là một kiểu bình thường kế thừa từ UserControl mà không cần xác định bất kỳ xmal nào (vì vậy không phải là một lớp một phần được chia thành hai tệp). Vấn đề là bạn không thể kế thừa xmal, vì vậy lớp cơ sở hoặc lớp con không cần phải có tệp xmal. Điều đó hoặc làm cho các lớp của bạn điều khiển tùy chỉnh thay vì điều khiển người dùng. Bằng cách đó, giao diện được xác định bên ngoài lớp một phần nhưng bạn sẽ mất tính dễ sử dụng Điều khiển người dùng.
Martin Harris

1
Vậy là xong: nếu bạn đặt BaseDataType thành một lớp bình thường kế thừa UserControl, thì nó sẽ hoạt động. Cảm ơn vô cùng.
Edward Tanguay

@Martin, bạn có thể muốn cập nhật câu trả lời của mình để phản ánh nhận xét của bạn và đó là câu trả lời thực sự.
Bryan Anderson

Có cách nào để làm cho các phần tử từ "cơ sở điều khiển" nằm trên các phần tử trên lớp kế thừa không?
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>    

1

Tôi đã tìm thấy câu trả lời trong bài viết này: http://www.paulstovell.com/xmlnsdefinition

Về cơ bản những gì được nói là bạn nên xác định một không gian tên XML trong tệp AssemlyInfo.cs, có thể được sử dụng trong XAML. Nó hoạt động với tôi, tuy nhiên tôi đã đặt lớp điều khiển người dùng cơ sở trong một DLL riêng biệt ...


0

Tôi đã gặp phải vấn đề tương tự nhưng cần có quyền kế thừa điều khiển từ một lớp trừu tượng, lớp này không được hỗ trợ bởi trình thiết kế. Điều đã giải quyết được vấn đề của tôi là làm cho usercontrol kế thừa từ cả một lớp tiêu chuẩn (kế thừa UserControl) và một giao diện. Cách này nhà thiết kế đang làm việc.

//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

Có định nghĩa một phần lớp được tạo bởi nhà thiết kế, bạn có thể mở nó một cách dễ dàng thông qua định nghĩa phương thức InitializeComponent (). Sau đó, chỉ cần thay đổi tính kế thừa một phần của lớp từ UserControl thành BaseDataType (hoặc bất kỳ phần nào bạn đã chỉ định trong định nghĩa lớp).

Sau đó, bạn sẽ có cảnh báo rằng phương thức InitializeComponent () bị ẩn trong lớp con.

Do đó, bạn có thể tạo một CustomControl làm khóa cơ sở thay vì UserControl để tránh định nghĩa một phần trong lớp cơ sở (như được mô tả trong một nhận xét).


Không thể chuyển đổi từ Controls.Login sang Controls.BaseControl.
Himilou,
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.