WPF UserControl, WPF UserControl'ü nasıl devralabilir?


95

Aşağıdaki WPF UserControl , çalışan DataTypeWholeNumber olarak adlandırılır .

Şimdi DataTypeDateTime ve DataTypeEmail , vb. Adında bir UserControl yapmak istiyorum .

Bağımlılık Özelliklerinin çoğu, tüm bu denetimler tarafından paylaşılacak ve bu nedenle , ortak yöntemlerini bir BaseDataType içine koymak ve bu UserControls'lerin her birinin bu temel türden miras almasını istiyorum .

Ancak, bunu yaptığımda şu hatayı alıyorum: Kısmi Bildirimin farklı temel sınıfları olmayabilir .

Öyleyse, UserControls ile kalıtımı nasıl uygulayabilirim, böylece paylaşılan işlevlerin tümü temel sınıfta olur?

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



    }
}

Görsel miras ile WPF geçici çözümü için bkz .: svetoslavsavov.blogspot.gr/2009/09/… veya
atadaki

Yanıtlar:


132

Xaml'deki ilk etiketi yeni basetype'ınızdan da miras alacak şekilde değiştirdiğinizden emin olun.

Yani

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

olur

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

Öyleyse, aşağıdaki yorumlardan ekstra ayrıntılar dahil olmak üzere tam cevabı özetlemek için:

  • Temel sınıf bir xaml dosyası içermemelidir. Tek bir (kısmi olmayan) cs dosyasında tanımlayın ve doğrudan Usercontrol'den miras alacak şekilde tanımlayın.
  • Alt sınıfın, hem arka planda cs kod dosyasında hem de xaml'nin ilk etiketinde (yukarıda gösterildiği gibi) temel sınıftan miras aldığından emin olun.

4
bu değişikliği yaptığımda şu hatayı alıyorum: "... DataTypes.BaseDataType, XAML kullanılarak tanımlandığı için bir XAML dosyasının kökü olamaz", bu döngüsel başvurudan nasıl çıkarsınız?
Edward Tanguay

9
Temel sınıfı, herhangi bir xmal tanımlamadan UserControl'den miras alan normal bir tür yapabilirseniz (yani, iki dosyaya bölünmüş kısmi bir sınıf olmaz). Sorun, xmal'i miras alamamanızdır, bu nedenle temel veya alt sınıfın bir xmal dosyasına sahip olması gerekmez. Ya bu ya da sınıflarınızı kullanıcı kontrolleri yerine özel kontroller yapın. Bu şekilde, görünüm kısmi sınıfın dışında tanımlanır, ancak bir Kullanıcı Denetiminin kullanım kolaylığını kaybedersiniz.
Martin Harris

1
İşte bu: BaseDataType'ı UserControl'ü miras alan normal bir sınıf yaparsanız, o zaman çalışır. Mükemmel, teşekkürler.
Edward Tanguay

@Martin cevabınızı yorumunuzu yansıtacak şekilde güncellemek isteyebilirsiniz ve bu gerçek cevaptır.
Bryan Anderson

"Kontrol temelindeki" öğelerin, kalıtımsal olan sınıftaki öğelerin üstünde olmasını sağlamanın bir yolu var mı?
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

Cevabı bu makalede buldum: http://www.paulstovell.com/xmlnsdefinition

Temel olarak söylenen, AssemlyInfo.cs dosyasında, XAML'de kullanılabilen bir XML ad alanı tanımlamanız gerektiğidir. Benim için çalıştı, ancak temel kullanıcı kontrol sınıfını ayrı bir DLL'ye yerleştirdim ...


0

Aynı sorunla karşılaştım, ancak denetimin tasarımcı tarafından desteklenmeyen soyut bir sınıftan miras alması gerekiyordu. Sorunumu çözen şey, kullanıcı kontrolünün hem standart bir sınıftan (UserControl'ü miras alan) hem de bir arabirimden devralması oldu. Tasarımcı bu şekilde çalışıyor.

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

Tasarımcı tarafından oluşturulmuş kısmi sınıf tanımı vardır, bunu InitializeComponent () yöntem tanımı aracılığıyla kolay bir şekilde açabilirsiniz. Ardından, kısmi sınıf mirasını UserControl'den BaseDataType'a (veya sınıf tanımında belirttiğiniz herhangi birine) değiştirin.

Bundan sonra, InitializeComponent () yönteminin alt sınıfta gizlendiğine dair uyarı alırsınız.

Bu nedenle, temel sınıfta kısmi tanımlamadan kaçınmak için UserControl yerine temel sınıf olarak bir CustomControl yapabilirsiniz (bir açıklamada açıklandığı gibi).


Controls.Login'den Controls.BaseControl'e dönüştürülemiyor.
Himilou
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.