2010-11-06 20 views
8

Espero que estés bien.Caliburn.Micro & Telerik WPF Controls

Estoy usando Caliburn.Micro con los controles WPF de Telerik para crear una interfaz con pestañas. Usando RadTabControl tengo el siguiente código;

<telerik:RadTabControl x:Name="Items" Grid.Row="1" TabStripPlacement="Bottom"> 
    <telerik:RadTabControl.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <Image Source="{Binding DisplayIcon}" Width="16" Height="16"/> 
       <TextBlock Text="{Binding DisplayName}"/> 
      </StackPanel> 
     </DataTemplate> 
    </telerik:RadTabControl.ItemTemplate> 
</telerik:RadTabControl> 

La ficha tiene la cabecera correcta pero el contenido sigue: ".../MyViewModel" (elipses reemplazar ruta completa) en lugar de la pantalla que se debe mostrar.

Si reemplazo <telerik:RadTabControl... con <TabControl..., todo funciona según lo previsto.

¿Qué me estoy perdiendo?

Respuesta

12

El sistema de convenciones de Caliburn solo está configurado para controles WPF que están listos para usar. Cuando ve el RabTabControl, no lo reconoce, por lo que buscó en su jerarquía de clases buscando algo que reconozca. En este caso, probablemente coincida con Selector o ItemsControl. Esta es la razón por la cual hay una aplicación parcial de las convenciones. Para obtener exactamente lo que desea, debe agregar una convención al ConventionManager para RadTabControl que haga exactamente lo que desea. Aquí es cómo se define la convención TabControl:

AddElementConvention<TabControl>(TabControl.ItemsSourceProperty, "ItemsSource", "SelectionChanged") 
.ApplyBinding = (viewModelType, path, property, element, convention) => { 
    if(!SetBinding(viewModelType, path, property, element, convention)) 
     return; 

    var tabControl = (TabControl)element; 
    if(tabControl.ContentTemplate == null && tabControl.ContentTemplateSelector == null && property.PropertyType.IsGenericType) { 
     var itemType = property.PropertyType.GetGenericArguments().First(); 
     if(!itemType.IsValueType && !typeof(string).IsAssignableFrom(itemType)) 
      tabControl.ContentTemplate = DefaultItemTemplate; 
    } 

    ConfigureSelectedItem(element, Selector.SelectedItemProperty, viewModelType, path); 

    if(string.IsNullOrEmpty(tabControl.DisplayMemberPath)) 
     ApplyHeaderTemplate(tabControl, TabControl.ItemTemplateProperty, viewModelType); 
}; 

Creo que debería ser capaz de tomar el código y con algunas modificaciones menores, que haga lo que usted quiere. Tenga en cuenta que algunos de los métodos invocados en el código anterior realmente existen en el ConventionManager, por lo que deberá corregirlos. Debe agregar su convención en la anulación de configuración de Bootstrapper. Para obtener una muestra adicional de esto, eche un vistazo al Bootstrapper de la plantilla WP7, que define convenciones personalizadas para Pivot y Panarama.

+1

Esto hizo el truco. Muchas gracias. – Dan

4

Caliburn.Micro.Telerik contiene convenciones para los controles WPF de Telerik, así como algunas otras cosas específicas de Telerik + WPF como una implementación de IWindowManager y dos aplicaciones con ejemplos.

Puede consultar el source code o el nuget package.

La convención para RadTabControl se parece a esto:

ConventionManager.AddElementConvention<RadTabControl>(RadTabControl.ItemsSourceProperty, 
                "ItemsSource", 
                "SelectionChanged") 
.ApplyBinding = (viewModelType, path, property, element, convention) => 
{ 
    if (!ConventionManager.SetBindingWithoutBindingOrValueOverwrite(viewModelType, 
                    path, 
                    property, 
                    element, 
                    convention, 
                    RadTabControl.ItemsSourceProperty)) 
     return false; 

    var tabControl = (RadTabControl) element; 
    if (tabControl.ContentTemplate == null 
     && tabControl.ContentTemplateSelector == null 
     && property.PropertyType.IsGenericType) 
    { 
     var itemType = property.PropertyType.GetGenericArguments().First(); 
     if (!itemType.IsValueType && !typeof (string).IsAssignableFrom(itemType)) 
      tabControl.ContentTemplate = ConventionManager.DefaultItemTemplate; 
    } 
    ConventionManager.ConfigureSelectedItem(element, 
              RadTabControl.SelectedItemProperty, 
              viewModelType, 
              path); 

    if (string.IsNullOrEmpty(tabControl.DisplayMemberPath)) 
     ConventionManager.ApplyHeaderTemplate(tabControl, 
               RadTabControl.ItemTemplateProperty, 
               RadTabControl.ItemTemplateSelectorProperty, 
               viewModelType); 
    return true; 
}; 

Espero que esto ayude ...