XAML 如何访问嵌套的自定义控件?

zzzyeukh  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(180)

这个问题来自于这个相关的问题。
存取巢状内部控件的其中一种方法,是在外部控件中建立相依性属性,并将值传递至内部控件。
如何从外部控件外部直接访问内部控件?

enxuqcxy

enxuqcxy1#

一种方法是将内部控件存储在公共属性中。
代码如下:

    • 内部控件. 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);
    }
}
    • 外部控件. 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;}
}
    • 一般. 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>
    • 主窗口. 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>
    • 主窗口. 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();
        }
    }
}

相关问题