Home > Blockchain >  How to access your nested custom control?
How to access your nested custom control?

Time:09-12

This question comes from this related question.

One way to access your nested inner control, is to create dependency-properties in the outer control and pass values to the inner control.

How can I access directly the inner control from outside the outer control?

CodePudding user response:

One way to do this, is to store the inner control in a public property.

Here's the code:

InnerControl.cs

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

namespace WinUI3CustomControlTest;

public sealed class InnerControl : Control
{
    public static readonly DependencyProperty InnerTextProperty =
        DependencyProperty.Register(
            nameof(InnerText),
            typeof(string),
            typeof(InnerControl),
            new PropertyMetadata(string.Empty));

    public InnerControl()
    {
        this.DefaultStyleKey = typeof(InnerControl);
    }

    public string InnerText
    {
        get => (string)GetValue(InnerTextProperty);
        set => SetValue(InnerTextProperty, value);
    }
}

OuterControl.cs

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

namespace WinUI3CustomControlTest;

[TemplatePart(Name = nameof(MyInnerControl), Type = typeof(InnerControl))]
public sealed class OuterControl : Control
{
    public OuterControl()
    {
        this.DefaultStyleKey = typeof(OuterControl);
    }

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        MyInnerControl = GetTemplateChild(nameof(MyInnerControl)) as InnerControl;
    }

    public InnerControl? MyInnerControl { get; private set;}
}

Generic.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:WinUI3CustomControlTest">

    <Style TargetType="local:OuterControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:OuterControl">
                    <StackPanel Orientation="Vertical">
                        <local:InnerControl x:Name="MyInnerControl" />
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style TargetType="local:InnerControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:InnerControl">
                    <StackPanel>
                        <TextBlock Text="{TemplateBinding InnerText}" />
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

MainWindow.xaml

<Window
    x:Class="WinUI3CustomControlTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:WinUI3CustomControlTest"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel>
        <Button
            Click="Button_Click"
            Content="Set text programmatically" />
        <local:OuterControl x:Name="MyOuterControl" />
    </StackPanel>

</Window>

MainWindow.xaml.cs

using Microsoft.UI.Xaml;
using System;

namespace WinUI3CustomControlTest;

public sealed partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (this.MyOuterControl.MyInnerControl is InnerControl innerControl)
        {
            innerControl.Text = DateTime.Now.ToString();
        }
    }
}
  • Related