User avatar
sfernandez
Site Admin
Posts: 1911
Joined: 22 Dec 2011, 19:20

Re: How to use DataTemplateSelector?

27 Mar 2015, 21:29

Hi,

I was able to run your sample (a bit more simplified) in the XamlPlayer:
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="TestPanel">
    <Grid.Resources>
        <DataTemplate x:Key="IconTextDataTemplate_key">
            <Grid HorizontalAlignment="Center" Margin="2,0,0,0" VerticalAlignment="Center">
                <TextBlock
                    HorizontalAlignment="Center"
                    Margin="0"
                    VerticalAlignment="Center"
                    Focusable="False"
                    FontSize="16"
                    Foreground="Black"
                    Text="{Binding StatusItemText}"
                    TextWrapping="NoWrap"/>
            </Grid>
        </DataTemplate>
        <StatusItemTemplateSelector x:Key="statusItemTemplateSelector"
            IconTextDataTemplate="{StaticResource IconTextDataTemplate_key}"/>
    </Grid.Resources>
    <ItemsControl x:Name="System_StatusBarArea"
        Width="200" Height="100"
        Background="Silver" BorderBrush="Gray" BorderThickness="4"
        ItemTemplateSelector="{StaticResource statusItemTemplateSelector}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Grid> 
struct StatusBar_Item : public BaseComponent
{
    StatusBar_Item(const NsChar* itemText) : mItemText(itemText) {}

    const NsChar* GetStatusItemText() const { return mItemText.c_str(); }

    NsString mItemText;

    NS_IMPLEMENT_INLINE_REFLECTION(StatusBar_Item, BaseComponent)
    {
        NsMeta<TypeId>("StatusBar_Item");
        NsProp("StatusItemText", &StatusBar_Item::GetStatusItemText);
    }
}; 
struct StatusItemTemplateSelector : public DataTemplateSelector
{
    StatusItemTemplateSelector() {}
    ~StatusItemTemplateSelector() {}

    DataTemplate* SelectTemplate(Core::BaseComponent* item, DependencyObject* container)
    {
        return _iconTextDataTemplate.GetPtr();
    }

    DataTemplate* GetIconTextDataTemplate() const
    {
        return _iconTextDataTemplate.GetPtr();
    }
    void SetIconTextDataTemplate(DataTemplate* pTemplate)
    {
        _iconTextDataTemplate.Reset(pTemplate);
    }

    Ptr<DataTemplate> _iconTextDataTemplate;

    NS_IMPLEMENT_INLINE_REFLECTION(StatusItemTemplateSelector, DataTemplateSelector)
    {
        NsMeta<TypeId>("StatusItemTemplateSelector");
        NsProp("IconTextDataTemplate",
            &StatusItemTemplateSelector::GetIconTextDataTemplate,
            &StatusItemTemplateSelector::SetIconTextDataTemplate);
    }
}; 
struct TestPanel : Grid
{
    TestPanel() {}
    ~TestPanel() {}

    void OnPostInit()
    {
        ItemsControl* ic = FindName<ItemsControl>("System_StatusBarArea");
        Ptr<Collection> items = *new Collection();
        Ptr<StatusBar_Item> item;

        item = *new StatusBar_Item("Left");
        items->Add(item.GetPtr());

        item = *new StatusBar_Item("Center");
        items->Add(item.GetPtr());

        item = *new StatusBar_Item("Right");
        items->Add(item.GetPtr());

        ic->SetItemsSource(items.GetPtr());
    }

    NS_IMPLEMENT_INLINE_REFLECTION(TestPanel, Grid)
    {
        NsMeta<TypeId>("TestPanel");
    }
}; 
Please let me know if it works for you. Perhaps you can expand this sample until you get the whole sample working.

NOTE: To specify the font family the # sign must be placed between the path and the family name, like this:
FontFamily="Fonts/#Arial" 
 
darthmaule2
Topic Author
Posts: 94
Joined: 23 Oct 2014, 19:54

Re: How to use DataTemplateSelector?

30 Mar 2015, 17:52

Yes - simplified to this extent, it is working for me now.
THANK YOU!

Now I'll start adding complexity back in one step at a time...
 
darthmaule2
Topic Author
Posts: 94
Joined: 23 Oct 2014, 19:54

Re: How to use DataTemplateSelector?

31 Mar 2015, 22:11

NO, IT ACTUALLY DID NOT WORK!!!
Sorry, I was using this in 3 places, and it turned out that in the place where I thought it was working, I had actually switched to a hardcoded ItemTemplate as a work around.

With more investigation, I verified that the StatusItemTemplateSelector was being instantiated, and the SelectTemplate() method was being called, but was returning NULL.
Unfortunately, the SetTextDataTemplate() was never called, so the selector had nothing to return. :(

Once I realized this, I added a name to my DataTemplate
       <DataTemplate x:Name="George" x:Key="TextDataTemplate_key" .........
and I added the following near the top of OnPostInit():
StatusItemTemplateSelector * myTemplateSelector =
               NsStaticCast<StatusItemTemplateSelector *>(ic->GetItemTemplateSelector());
DataTemplate* myTemplate = FindName<DataTemplate>("George");
		if (myTemplateSelector && myTemplate)
		{
			myTemplateSelector->SetTextDataTemplate(myTemplate);
		}
Once SetTextDataTemplate() was actually called, then the template selector finally worked.

This seems to be a bug in the initialization of a DataTemplateSelector from xaml.
 
User avatar
sfernandez
Site Admin
Posts: 1911
Joined: 22 Dec 2011, 19:20

Re: How to use DataTemplateSelector?

01 Apr 2015, 18:55

As explained in the corresponding bugtracker ticket, this issue is fixed and will be available in the next 1.2.2 release.

We thank you for the valuable feedback ;)

Who is online

Users browsing this forum: asusralis, Google [Bot] and 1 guest