I inherited my Control
for HeaderedContentControl
. I need to hide the child control when user clicked the parent control, but I do not know how to access its child control.
Here is my code.
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;
}
}
CodePudding user response:
You could set the Visibility
of the child control, which is the Content
of the control.
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;
}
If you create a custom control, you could alternatively specify a TemplatePart
for a ContentPresenter
. Then you can always show and hide the ContentPresenter
which shows the Content
, instead of depending on the actual child controls. This would also work for non-UIElement
children like a string
.
[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;
}
}
The only requirement would be that your control template contains this part.
<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>
See Creating a Control That Has a Customizable Appearance for reference.