Page 1 of 1

How to properly get element inside ControlTemplate in Native code

Posted: 06 Dec 2024, 22:50
by Mikhail Yanakayev
Hello,

In XAML I have construction like this:
<Grid Grid.Row="1" Grid.Column="1">
	<ItemsControl x:Name="MyGrid"  ItemsSource="{Binding MyList}" ItemTemplate="{DynamicResource MyRow}" Grid.Row="1" Grid.Column="1" VirtualizingPanel.ScrollUnit="Pixel" VirtualizingPanel.CacheLengthUnit="Item" >
		<ItemsControl.Template>
			<ControlTemplate>
				<ScrollViewer x:Name="MyScroll"  CanContentScroll="True" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Visible" Template="{StaticResource Template.ScrollViewer}" PanningMode="VerticalOnly" Focusable="False" >
					<VirtualizingStackPanel IsItemsHost="True" />
				</ScrollViewer>
			</ControlTemplate>
		</ItemsControl.Template>
	</ItemsControl>
</Grid>
Then I'm trying to get this element by following code:
Noesis::ItemsControl* myGridControl = uiControl->FindName<Noesis::ItemsControl>("MyGrid");
//m_myGridControl->ApplyTemplate();
Noesis::BaseComponent* component = myGridControl->GetTemplateChild("MyScroll");
Here "component" receives nullptr. Also I've tried to call ApplyTemplate before getting child and also make child class with OnApplyTemplate callback that never called.
So how I can get ScrollViewer element from this template?

Also is it possible than scroll this ScrollViewer to needed row considering that I'm using virtualization for it?

Thank you!

Re: How to properly get element inside ControlTemplate in Native code

Posted: 11 Dec 2024, 10:13
by sfernandez
Hi,

When are you executing this code?
You should wait until the control gets Initialized (you'll need to manually call ApplyTemplate in this case) or Loaded (template will be already applied).
You can hook to those events when your user control is created:
    MyControl()
    {
        InitializeComponent();

        Loaded() += [](BaseComponent* sender, const RoutedEventArgs&)
        {
            FrameworkElement* root = (FrameworkElement*)sender;
            ItemsControl* ic = root->FindName<ItemsControl>("MyGrid");
            BaseComponent* sv = ic->GetTemplateChild<ScrollViewer>("MyScroll");
            ...
        };
    }
Would that work for you?

Re: How to properly get element inside ControlTemplate in Native code

Posted: 11 Dec 2024, 14:10
by Mikhail Yanakayev
Yeah, seems it works.

What about second question? I've tried to call ScrollViewer::ScrollToBottom for virtualized ScrollView, and it scrolled not to bottom but seems to bottom part of current chunk that loaded at the moment. Is it possible to scroll it to the real end (or to exact place) of such ScrollView?

Re: How to properly get element inside ControlTemplate in Native code

Posted: 12 Dec 2024, 21:00
by sfernandez
In order to scroll in a virtualized panel, as the containers are probably not visible in the ScrollViewer, the panel needs to generate the containers for the new position. So you have to indicate that to the virtualized panel:
void ScrollToItem(VirtualizingPanel* panel, int index)
{
  panel->BringIndexIntoView(index);
}
Could you try something like that?

Re: How to properly get element inside ControlTemplate in Native code

Posted: 13 Dec 2024, 00:59
by Mikhail Yanakayev
Yes, it works.
For now I can't do this right after adding all elements to the scrollviewer (seems they're not generated at the moment), but it's another story.

Thanks!

Re: How to properly get element inside ControlTemplate in Native code

Posted: 13 Dec 2024, 13:15
by sfernandez
Glad to help!