Caliburn.Micro & Telerik WPF Controls
Asked Answered
E

2

8

Hope you're all well.

I am using Caliburn.Micro with Telerik's WPF controls to build a tabbed interface. Using RadTabControl I have the following code;

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

The tab has the correct header but the contents read ".../MyViewModel" (ellipses replace full path) instead of the Screen that should be displayed.

If I replace <telerik:RadTabControl... with <TabControl... this all works as intended.

What am I missing?

Epiblast answered 6/11, 2010 at 13:15 Comment(0)
W
12

Caliburn's conventions system is only configured for WPF controls that are out-of-the-box. When it sees the RabTabControl, it doesn't recognize it, so it searched it's class hierarchy looking for something it does recognize. In this case, it probably matches on either Selector or ItemsControl. This is why there is a partial application of conventions. In order to get exactly what you want, you need to add a convention to the ConventionManager for RadTabControl that does exactly what you want. Here is how the TabControl convention is defined:

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

I think you should be able to take the code and with a few minor modifications, make it do what you want. Note that some of the methods called in the above code actually exist on the ConventionManager, so you will need to fix that up. You should add your convention in your Bootstrapper's Configure override. For an additional sample of this, have a look at the WP7 template's Bootstrapper, which defines custom conventions for Pivot and Panarama.

Whangee answered 6/11, 2010 at 15:10 Comment(0)
D
4

Caliburn.Micro.Telerik contains conventions for Telerik's WPF controls, as well as some other Telerik+WPF specific stuff like an IWindowManager implementation and two applications with examples.

You can check out the source code or the nuget package.

The convention for RadTabControl looks like this:

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;
};

Hope this helps...

Decimate answered 19/7, 2012 at 15:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.