2008-11-06 21 views
29

Soy bastante nuevo en WPF y tengo un problema con la herencia de un control de usuario.Heredar de un UserControl en WPF

Creé un Control de usuario y ahora necesito heredar de ese control y agregar algunas funciones más.

¿Alguien ha hecho este tipo de cosas antes? Cualquier ayuda sería muy apreciada.

Gracias

+2

para la solución de WPF con herencia visual, consulte: http://svetoslavsavov.blogspot.gr/2009/09/user-control-inheritance-in-wpf.html o para definir explícitamente la GUI en el antecesor, vea http: // support.microsoft.com/kb/957231 –

Respuesta

14

AFAIK no puede heredar el xaml, solo puede heredar el código.

Recientemente encontramos el mismo problema en nuestro proyecto. La forma en que terminamos resolviendo nuestro problema fue crear un control de usuario y agregarlo al control de usuario "secundario".

Si eso no funciona/ayudar a echar un vistazo a esto: http://geekswithblogs.net/lbugnion/archive/2007/03/02/107747.aspx1

26

Bueno .. a crear su control de la base

public abstract class BaseUserControl : UserControl{...} 

a continuación en el archivo XAML:

<Controls:BaseUserControl x:Class="Termo.Win.Controls.ChildControl" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:Controls="clr-namespace:Namespace.Of.Your.BaseControl"> 

Y eso debería funcionar.

EDIT: Hmm .. este ejemplo es útil cuando tiene un control de base sin XAML y luego hereda de él. A la inversa (desde un control de base con Xaml), no estoy seguro de cómo puedes hacerlo.

EDIT2: Aparentemente de this post + comments supongo que lo que desea podría no ser posible.

+1

Esta solución funcionó para mí. – GeekyMonkey

+2

Por lo que puedo recordar, el diseñador se queja cuando intenta heredar una clase abstracta en XAML. De lo contrario, esto debería funcionar bien. – Entrodus

+0

Esto también funcionó para mí. ¡Gracias! –

4

es posible que tenga un poco de una solución: Composición en lugar de la herencia - Me han llegado con el control, que tiene 'ranuras de contenido' asignable desde el exterior a través de enlace de datos, mira mi SO thread.

Ejemplo de uso:

<UserControl ... > 

    <!-- My wrapping XAML --> 
     <Common:DialogControl> 
       <Common:DialogControl.Heading> 
         <!-- Slot for a string --> 
       </Common:DialogControl.Heading> 
       <Common:DialogControl.Control> 
         <!-- Concrete dialog's content goes here --> 
       </Common:DialogControl.Control> 
       <Common:DialogControl.Buttons> 
         <!-- Concrete dialog's buttons go here --> 
       </Common:DialogControl.Buttons> 
     </Common:DialogControl> 
    <!-- /My wrapping XAML --> 

</UserControl> 

Junto con un código de manejo de código subyacente sería un componente buena base para las ventanas de diálogo.

2

Puede lograr esto usando delegate.

Esencialmente, necesita crear una interfaz (YourInterface) que finalice la funcionalidad que desea, luego haga que tanto el control de usuario como su clase implementen esa interfaz.

A continuación, asegúrese de que el control de usuario hace referencia a un objeto del tipo IYourInterface, de modo que cuando su control de usuario intente invocar un método del Interface, invoque el método de su clase.

Dado que tanto el control de usuario como la clase implementan la misma interfaz, pueden verse como el mismo tipo de objeto, lo que significa que puede ponerlos a ambos en una colección de objetos del tipo IYourInterface. Esto debería darle el comportamiento que desea.

En ASP.NET. Utilizo esta técnica a menudo, haciendo que mis clases hereden de los antepasados ​​abstract class. No entiendo por qué WPF no es compatible con esto. :(

1

No se puede heredar el que uno mismo código XAML Sin embargo la creación de una clase abstracta del código subyacente, le permitirá editar en código detrás, de un objeto de clase derivada

Código Xaml:.. {Window1.xaml }

<Window 
x:Class="WPFSamples.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Height="auto" Width="256" Title="WPF Sameples"> 
    <Grid> 
    <Button x:Name="Button1" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Click Me"/> 
    </Grid> 
</Window> 

CodeBehind: {} Window1.xaml.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

namespace WPFSamples 
{ 
    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public abstract partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

clase derivada: {} DisabledButtonWindow.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace WPFSamples 
{ 
    public sealed class DisabledButtonWindow : Window1 
    { 
     public DisabledButtonWindow() 
     { 
      Button1.IsEnabled = false; 
     } 
    } 
} 

Aunque no puede heredar de la fuente wpf, puede utilizar este control "Ventana1" como plantilla para todos los demás controles derivados.

1

creo que se puede hacer esto, pero que va a tener que redefinir las funciones y posiblemente algunas otras cosas que haga referencia en el XAML en la clase hija.

IE si tiene un evento de clic de botón al que se suscribe en la clase base xaml, necesitará anular el clic del botón en la clase secundaria y llamar al evento de clic del botón de clase base.

no es cien por ciento seguro de los detalles, ya que es mi código de compañeros de trabajo que estoy sacando de, pero considera que la daría un principio a todos aquellos que buscan implementar esto en el futuro.

Cuestiones relacionadas