Acceso directo a un control en WPF

Tengo un TabControl con múltiples TabItems. En cada TabItem debe haber este UserControl en particular. Ahora mismo estoy creando X instancias del control donde X es el número de TabItems que tengo. Entonces esta parece una mala manera de hacerlo. Entonces me pregunto si hay alguna manera de tener 1 instancia de un control, pero múltiples ubicaciones para ello. Sé que cada control solo puede tener un padre, por lo que parece que la respuesta es no.

[TabItem1] 
[CommandLine Control]
[Content unique to TabItem1] 

[TabItem2] 
[CommandLine Control]
[Content unique to TabItem2]

¿Es posible tener una instancia de [CommandLine Control] pero en estos dos lugares?

preguntado el 16 de mayo de 11 a las 17:05

5 Respuestas

Si usa una plantilla de datos para su control y enlaza el control de pestañas a una colección, entonces el marco solo creará una instancia del control e intercambiará su contexto de datos a medida que cambie los elementos de las pestañas.

Puede encontrar una discusión más detallada aquí: ¿Por qué los controles de pestañas reutilizan las instancias de vista al cambiar de pestaña?

contestado el 23 de mayo de 17 a las 15:05

Puede lograr esto usando disparadores que aseguran que el control no esté en dos lugares al mismo tiempo, por ejemplo

<TabControl>
    <TabControl.Resources>
        <!-- Define control which is to be reused in resources -->
        <TextBox x:Key="SharedTB" Text="test"/>

        <!-- This style gets the shared control only if the parent
             TabItem is selected -->            
        <Style x:Key="LoadTBStyle" TargetType="{x:Type ContentControl}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=TabItem}, Path=IsSelected}"
                                         Value="True">
                    <Setter Property="Content" Value="{StaticResource SharedTB}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TabControl.Resources>
    <TabItem Header="TabItem 1">
        <StackPanel>
            <TextBlock Text="Lorem Ipsum"/>
            <ContentControl Style="{StaticResource LoadTBStyle}"/>
        </StackPanel>
    </TabItem>
    <TabItem Header="TabItem 2">
        <StackPanel>
            <TextBlock Text="Dolor Sit"/>
            <ContentControl Style="{StaticResource LoadTBStyle}"/>
        </StackPanel>
    </TabItem>
</TabControl>

contestado el 16 de mayo de 11 a las 22:05

¿Es el control realmente más o menos un control compartido? Quiero decir, si realmente desea que un control esté en más lugares que 1, entonces sería mejor alojarlo fuera de TabItem para que se pueda acceder a él desde cualquiera de los elementos de la pestaña que lo necesiten.

A partir de su ejemplo, parece que lo mejor sería generar los elementos. Personalmente, tendría la propiedad TabControls Items vinculada a una colección de ViewModels que aloja un TabItem. Cada uno de ellos tendría una instancia creada en tiempo de ejecución del UserControl (con ViewModel y contenido asociados).

contestado el 16 de mayo de 11 a las 22:05

Parece que lo que está buscando se puede lograr mediante el uso de una plantilla.

Mire este enlace para ver un ejemplo de una plantilla de elemento de tabulación: http://msdn.microsoft.com/en-us/library/ms752032.aspx

contestado el 16 de mayo de 11 a las 22:05

¿No terminaría eso creando todos los controles? Supongo (¿quizás erróneamente?) Que el OP estaba preocupado por el uso de recursos para cargar tantas instancias del control del usuario. - Tim

@Tim, supongo, estarías en lo cierto. Esto aún crearía una nueva instancia del control para cada elemento de pestaña. Sin embargo, no creo que esto deba ser un problema para el OP. Los problemas de memoria no son realmente un problema, ya que el control se puede descargar al cambiar a un nuevo TabItem. Estoy de acuerdo con su respuesta de que el OP tal vez podría cambiar dónde está el control con el código subyacente, pero que podría causar problemas. La única otra opción en la que podría pensar sería hacer que el control sea un recurso en el control contenedor y hacer referencia a eso en cada tabItem (pensamiento inseguro). - JMcCarty

No creo que pueda poner un control en los recursos y cargarlo en varios lugares. Creo que da el mismo error que si intenta agregar manualmente el mismo control a varios padres. Aunque podría estar equivocado. - Tim

No hay forma de tener un "atajo" de la forma que usted describe que yo sepa, porque su control de usuario solo puede tener un padre.

Lo único que se me ocurre es cambiarlo manualmente (mediante código subyacente) cuando el usuario hace clic en una pestaña diferente. Pero el "tartamudeo" que puede causar a medida que lo cambia (aunque es mejor en WPF, me imagino que en otros marcos) podría ser tan malo como cualquier problema de uso de recursos que esté viendo al tener múltiples instancias del control de usuario .

Supongo que otra cosa sería almacenar en caché la creación de los controles de usuario para que solo se carguen si la persona realmente hace clic en la pestaña.

contestado el 16 de mayo de 11 a las 22:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.