Как связать / обернуть событие дочернего элемента управления в событие пользовательского элемента управления в C #? - PullRequest
0 голосов
/ 02 июня 2019

Я создаю пользовательский элемент управления (или шаблонный, если вы не возражаете), но я не могу понять, как связать событие (щелчок) кнопки внутри пользовательского элемента управления с событием Click пользовательского элемента управления сам по себе.

Я искал в Интернете, но какое-то решение было только для WPF (включая классы, недоступные на платформе UWP), некоторые - для Visual Basic, другие - не совсем в моем случае и так далее ...

Вот код, который работает до сих пор, для лучшей очистки (обратите внимание, я изменил имя проекта и пространства имен, чтобы скрыть его, вместо этого вместо «SomeClass»):

Пользовательский элемент управления, IconButton.cs :

public sealed class IconButton : Control
{
    public IconButton()
    {
        this.DefaultStyleKey = typeof(IconButton);

    }



    public Boolean IconButtonIsLabelVisible
    {
        get { return (Boolean)GetValue(IconButtonIsLabelVisibleProperty); }
        set { SetValue(IconButtonIsLabelVisibleProperty, value); }
    }
    public static readonly DependencyProperty IconButtonIsLabelVisibleProperty =
        DependencyProperty.Register("IconButtonIsLabelVisible", typeof(Boolean), typeof(IconButton), new PropertyMetadata(true));



    public String IconButtonLabel
    {
        get { return (String)GetValue(IconButtonLabelProperty); }
        set { SetValue(IconButtonLabelProperty, value); }
    }
    public static readonly DependencyProperty IconButtonLabelProperty =
        DependencyProperty.Register("IconButtonLabel", typeof(String), typeof(IconButton), new PropertyMetadata("Content"));



    public Double IconButtonLabelMargin
    {
        get { return (Double)GetValue(IconButtonLabelMarginProperty); }
        set { SetValue(IconButtonLabelMarginProperty, value); }
    }
    public static readonly DependencyProperty IconButtonLabelMarginProperty =
        DependencyProperty.Register("IconButtonLabelMargin", typeof(Double), typeof(IconButton), new PropertyMetadata(10));



    public Style IconButtonStyle
    {
        get { return (Style)GetValue(IconButtonStyleProperty); }
        set { SetValue(IconButtonStyleProperty, value); }
    }
    public static readonly DependencyProperty IconButtonStyleProperty =
        DependencyProperty.Register("IconButtonStyle", typeof(Style), typeof(IconButton), new PropertyMetadata(null));



    public IconElement IconButtonIcon
    {
        get { return (IconElement)GetValue(IconButtonIconProperty); }
        set { SetValue(IconButtonIconProperty, value); }
    }
    public static readonly DependencyProperty IconButtonIconProperty =
        DependencyProperty.Register("IconButtonIcon", typeof(IconElement), typeof(IconButton), new PropertyMetadata(0));

}

Общий файл шаблона xaml, Generic.xaml :

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

<Style TargetType="local:IconButton">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:IconButton">
                <Button x:Name="ClickButton" Style="{TemplateBinding IconButtonStyle}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" Command="{TemplateBinding Command}" CommandParameter="{TemplateBinding CommandParameter}">
                    <Grid Margin="{TemplateBinding Padding}">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>

                        <ContentPresenter x:Name="Content"
                                Content="{TemplateBinding IconButtonIcon}"
                                Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center"/>

                        <Grid Grid.Column="1" Width="{TemplateBinding IconButtonLabelMargin}"/>

                        <TextBlock Grid.Column="2" Text="{TemplateBinding IconButtonLabel}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center"/>
                    </Grid>
                </Button>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

И MainPage.xaml , где я хотел бы использовать IconButton:

<Page
x:Class="SomeClass"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SomeClass"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:testControls="using:SomeClass.Controls"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid>
    <testControls:IconButton x:Name="TestButton" Click"?" IconButtonLabelMargin="5" HorizontalAlignment="Center" Foreground="Aqua" VerticalAlignment="Center" Background="Transparent" >
        <testControls:IconButton.IconButtonIcon>
            <SymbolIcon Symbol="Preview"/>
        </testControls:IconButton.IconButtonIcon>
    </testControls:IconButton>
</Grid>

Итак, учитывая этот код, я бы хотел каким-то образом связать событие Click кнопки ClickButton в шаблон xaml IconButton к событию Click по умолчанию Сам элемент управления IconButton, так что он может быть легко использован на главной странице просто указав событие Click.

Спасибо за доброту и внимание.

С уважением.

1 Ответ

1 голос
/ 03 июня 2019

Для этого необходимо переопределить метод OnApplyTemplate в вашем элементе управления, найти именованную часть шаблона в вашем элементе управления и вызвать событие в вашей оболочке.

Внутри вашего пользовательского элемента управления:

ButtonBase clickButtonPart = null;
public const string ClickButtonTemplatePartName = "ClickButton";
public event EventHandler Click;

protected override void OnApplyTemplate()
{
  // In case the template changes, you want to stop listening to the
  // old button's Click event.
  if (clickButtonPart != null)
  {
    clickButtonPart.Click -= ClickForwarder;
    clickButtonPart = null;
  }

  // Find the template child with the special name. It can be any kind
  // of ButtonBase in this example.
  clickButtonPart = GetTemplateChild(ClickButtonTemplatePartName) as ButtonBase;

  // Add a handler to its Click event that simply forwards it on to our
  // Click event.
  if (clickButtonPart != null)
  {
    clickButtonPart.Click += ClickForwarder;
  }
}

private void ClickForwarder(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
  Click?.Invoke(this, null);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...