如何在我的自定义控件中更改子控件的可见性?

How to change visibility of child control in my customized Control?

我为 HeaderedContentControl 继承了我的 Control。我需要在用户点击父控件时隐藏子控件,但我不知道如何访问它的子控件。

这是我的代码。

public class MyHeaderedContentControl : HeaderedContentControl
{
    public static readonly DependencyProperty ClickToHideProperty =
        DependencyProperty.Register("ClickToHide", typeof(bool), typeof(MyHeaderedContentControl),
            new PropertyMetadata(null));

    public bool ClickToHide
    {
        get => (bool)GetValue(ClickToHideProperty);
        set => SetValue(ClickToHideProperty, value);
    }

    protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        base.OnPreviewMouseLeftButtonDown(e);

        //TODO Hide one child control when user clicked the parent control

        e.Handled = true;
    }
}

你可以设置控件的Visibility of the child control, which is the Content

protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
   base.OnPreviewMouseLeftButtonDown(e);

   // Only a click on this control is handled, not children.
   if (!e.Source.Equals(this))
      return;

   // The content must be at least a UI element in order to access the Visibility property.
   if (Content is UIElement uiElement)
   {
      // If the child (Content) is visible, collapse it, if it is collapsed, make it visible.
      uiElement.Visibility = uiElement.Visibility == Visibility.Collapsed
         ? Visibility.Visible
         : Visibility.Collapsed;
   }

   e.Handled = true;
}

如果您创建自定义控件,您也可以指定 TemplatePart for a ContentPresenter。然后,您始终可以显示和隐藏显示 ContentContentPresenter,而不是依赖于实际的子控件。这也适用于 string 等非 UIElement 儿童。

[TemplatePart(Name = "PART_ContentPresenter", Type = typeof(ContentPresenter))]
public class MyHeaderedContentControl : HeaderedContentControl
{
   private ContentPresenter _contentPresenter;

   public static readonly DependencyProperty ClickToHideProperty =
      DependencyProperty.Register("ClickToHide", typeof(bool), typeof(MyHeaderedContentControl),
         new PropertyMetadata(null));

   public bool ClickToHide
   {
      get => (bool)GetValue(ClickToHideProperty);
      set => SetValue(ClickToHideProperty, value);
   }

   public override void OnApplyTemplate()
   {
      base.OnApplyTemplate();
      _contentPresenter = GetTemplateChild("PART_ContentPresenter") as ContentPresenter;
   }

   protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
   {
      base.OnPreviewMouseLeftButtonDown(e);

      // Only a click on this control is handled, not children.
      if (_contentPresenter is null || !e.Source.Equals(this))
         return;

      // If the child (Content) is visible, collapse it, if it is collapsed, make it visible.
      _contentPresenter.Visibility = _contentPresenter.Visibility == Visibility.Collapsed
            ? Visibility.Visible
            : Visibility.Collapsed;

      e.Handled = true;
   }
}

唯一的要求是您的控件模板包含此部分。

<Style TargetType="{x:Type local:MyHeaderedContentControl}">
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="{x:Type local:MyHeaderedContentControl}">
            <ContentPresenter x:Name="PART_ContentPresenter"/>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

参考Creating a Control That Has a Customizable Appearance