kristoffer.sjoo
Topic Author
Posts: 3
Joined: 08 Apr 2024, 07:52

Hybrid UserControl

08 Apr 2024, 08:18

I spent some time last week trying to write a subclass to UserControl which accepts XAML children - a sort of custom StackPanel which allows me to add a header and frame the contents as I like. What I want is to be able to do is something like the following
<MultiContentControl>
  <TextBlock Text="Custom content 1"/>
  <TextBlock Text="Custom content 2"/>
</MultiContentControl>
where the "Custom content" items would be displayed through a ContentPresenter (or a variant of it) appearing in the Template of the HybridControl. The motivation is to be able to write more compact XAML and reuse the same header-body layout in many places but with different types of content.

What I tried was to inherit from UserControl, to get the basic functionality of instantiating a "HybridControl.xaml" template, but I also borrowed the following from StackPanel:
GetChildren, CreateChildrenCollection, EnsureChildrenCollection, GetLogicalChildrenCount, GetLogicalChild, OnInit
I also did
	NsMeta<Noesis::ContentPropertyMetaData>( "Children" );
	NsProp( "Children", &MultiContentControl::GetChildren );
as the content property metadata seemed to be the way to direct the XAML body - the "custom content" entries - to my Noesis object.

I did a lot of experimentation but only managed to get so far as to reproduce the UserControl behavior, and trying to hook anything up from within the MultiContentControl's Template to the Children property of the TemplatedParent led to a run-time crash.

Is this supposed to be possible? Is there a known way to do it?
 
User avatar
sfernandez
Site Admin
Posts: 3001
Joined: 22 Dec 2011, 19:20

Re: Hybrid UserControl

10 Apr 2024, 11:16

Hi Kristoffer,

UserControl (which inherits from ContentControl) already exposes a ContentPropertyMetadata for the Content property, so it will conflict with your custom class and it won't work as you expected.

For adding multiple children, have you considered using an ItemsControl? You can define the ItemsControl template to specify the header-body layout and a custom ItemsPanel to specify the layout of children.
<ItemsControl Width="300" Height="200">
  <ItemsControl.Template>
    <ControlTemplate TargetType="ItemsControl">
      <Border CornerRadius="10" BorderBrush="Black" BorderThickness="2" Background="WhiteSmoke" Padding="15">
        <ItemsPresenter/>
      </Border>
    </ControlTemplate>
  </ItemsControl.Template>
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <UniformGrid Columns="2"/>
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <TextBlock Text="Custom content 1"/>
  <TextBlock Text="Custom content 2"/>
</ItemsControl>
And if the children are provided by a data collection, then it would be as easy as bind it in the ItemsControl.ItemsSource, and specify an ItemTemplate to define the appearance of the items.

Is this what you're looking for?
 
kristoffer.sjoo
Topic Author
Posts: 3
Joined: 08 Apr 2024, 07:52

Re: Hybrid UserControl

12 Apr 2024, 13:02

There's no data collection involved, just the XAML - in my example, two TextBlocks. Note that they would not necessarily be two, and not necessarily TextBlocks, and not necessarily the same as each other. Basically, I want to be able to use it just like I would a StackPanel. Can I use an ItemCollection in this instance?
 
User avatar
sfernandez
Site Admin
Posts: 3001
Joined: 22 Dec 2011, 19:20

Re: Hybrid UserControl

19 Apr 2024, 12:44

As I mentioned before you can use any kind of element for each item in the ItemsControl, simple TextBlocks or whole panels, for example:
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <ItemsControl Width="200" Height="200">
    <TextBlock Text="Header" FontSize="20" TextAlignment="Center"/>
    <UniformGrid Columns="2">
      <Button Content="Button 1"/>
      <Button Content="Button 2"/>
    </UniformGrid>
    <TextBlock Text="Sub-Section" Margin="0,5"/>
    <WrapPanel ItemWidth="50">
      <RadioButton HorizontalAlignment="Center" IsChecked="True"/>
      <RadioButton HorizontalAlignment="Center"/>
      <RadioButton HorizontalAlignment="Center"/>
      <RadioButton HorizontalAlignment="Center"/>
      <RadioButton HorizontalAlignment="Center"/>
      <RadioButton HorizontalAlignment="Center"/>
      <RadioButton HorizontalAlignment="Center"/>
      <RadioButton HorizontalAlignment="Center"/>
    </WrapPanel>
  </ItemsControl>
</Grid>
 
kristoffer.sjoo
Topic Author
Posts: 3
Joined: 08 Apr 2024, 07:52

Re: Hybrid UserControl

24 Apr 2024, 09:33

Alright, thanks for your help. I'm getting very close to what I want by using HeaderedItemsControl, with a default Style. The key was that I was unaware that you could provide ItemsControl with content in XAML like this and of the existence of ItemsPresenter.

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot], Semrush [Bot], tandr and 3 guests