129 lines
5.1 KiB
C#
129 lines
5.1 KiB
C#
using CommunityToolkit.Diagnostics;
|
|
using Windows.UI.Xaml;
|
|
using Windows.UI.Xaml.Controls;
|
|
using Windows.UI.Xaml.Hosting;
|
|
using Windows.UI.Xaml.Markup;
|
|
|
|
namespace Wino.Controls;
|
|
|
|
[ContentProperty(Name = nameof(Content))]
|
|
public partial class WinoExpander : Control
|
|
{
|
|
private const string PART_HeaderGrid = "HeaderGrid";
|
|
private const string PART_ContentAreaWrapper = "ContentAreaWrapper";
|
|
private const string PART_ContentArea = "ContentArea";
|
|
|
|
private ContentControl HeaderGrid;
|
|
private ContentControl ContentArea;
|
|
private Grid ContentAreaWrapper;
|
|
|
|
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(nameof(Header), typeof(UIElement), typeof(WinoExpander), new PropertyMetadata(null));
|
|
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(nameof(Content), typeof(UIElement), typeof(WinoExpander), new PropertyMetadata(null));
|
|
public static readonly DependencyProperty IsExpandedProperty = DependencyProperty.Register(nameof(IsExpanded), typeof(bool), typeof(WinoExpander), new PropertyMetadata(false, new PropertyChangedCallback(OnIsExpandedChanged)));
|
|
public static readonly DependencyProperty TemplateSettingsProperty = DependencyProperty.Register(nameof(TemplateSettings), typeof(WinoExpanderTemplateSettings), typeof(WinoExpander), new PropertyMetadata(new WinoExpanderTemplateSettings()));
|
|
|
|
public UIElement Content
|
|
{
|
|
get { return (UIElement)GetValue(ContentProperty); }
|
|
set { SetValue(ContentProperty, value); }
|
|
}
|
|
|
|
public WinoExpanderTemplateSettings TemplateSettings
|
|
{
|
|
get { return (WinoExpanderTemplateSettings)GetValue(TemplateSettingsProperty); }
|
|
set { SetValue(TemplateSettingsProperty, value); }
|
|
}
|
|
|
|
public bool IsExpanded
|
|
{
|
|
get { return (bool)GetValue(IsExpandedProperty); }
|
|
set { SetValue(IsExpandedProperty, value); }
|
|
}
|
|
|
|
public UIElement Header
|
|
{
|
|
get { return (UIElement)GetValue(HeaderProperty); }
|
|
set { SetValue(HeaderProperty, value); }
|
|
}
|
|
|
|
protected override void OnApplyTemplate()
|
|
{
|
|
base.OnApplyTemplate();
|
|
|
|
HeaderGrid = GetTemplateChild(PART_HeaderGrid) as ContentControl;
|
|
ContentAreaWrapper = GetTemplateChild(PART_ContentAreaWrapper) as Grid;
|
|
ContentArea = GetTemplateChild(PART_ContentArea) as ContentControl;
|
|
|
|
Guard.IsNotNull(HeaderGrid, nameof(HeaderGrid));
|
|
Guard.IsNotNull(ContentAreaWrapper, nameof(ContentAreaWrapper));
|
|
Guard.IsNotNull(ContentArea, nameof(ContentArea));
|
|
|
|
var clipComposition = ElementCompositionPreview.GetElementVisual(ContentAreaWrapper);
|
|
clipComposition.Clip = clipComposition.Compositor.CreateInsetClip();
|
|
|
|
ContentAreaWrapper.SizeChanged += ContentSizeChanged;
|
|
HeaderGrid.Tapped += HeaderTapped;
|
|
}
|
|
|
|
private void ContentSizeChanged(object sender, SizeChangedEventArgs e)
|
|
{
|
|
TemplateSettings.ContentHeight = e.NewSize.Height;
|
|
TemplateSettings.NegativeContentHeight = -1 * (double)e.NewSize.Height;
|
|
}
|
|
|
|
private void HeaderTapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
|
|
{
|
|
// Tapped is delegated from executing hover action like flag or delete.
|
|
// No need to toggle the expander.
|
|
|
|
if (Header is MailItemDisplayInformationControl itemDisplayInformationControl &&
|
|
itemDisplayInformationControl.IsRunningHoverAction)
|
|
{
|
|
itemDisplayInformationControl.IsRunningHoverAction = false;
|
|
return;
|
|
}
|
|
|
|
IsExpanded = !IsExpanded;
|
|
}
|
|
|
|
private static void OnIsExpandedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
|
|
{
|
|
if (obj is WinoExpander control)
|
|
control.UpdateVisualStates();
|
|
}
|
|
|
|
private void UpdateVisualStates()
|
|
{
|
|
VisualStateManager.GoToState(this, IsExpanded ? "Expanded" : "Collapsed", true);
|
|
}
|
|
}
|
|
|
|
#region Settings
|
|
|
|
public class WinoExpanderTemplateSettings : DependencyObject
|
|
{
|
|
public static readonly DependencyProperty HeaderHeightProperty = DependencyProperty.Register(nameof(HeaderHeight), typeof(double), typeof(WinoExpanderTemplateSettings), new PropertyMetadata(0.0));
|
|
public static readonly DependencyProperty ContentHeightProperty = DependencyProperty.Register(nameof(ContentHeight), typeof(double), typeof(WinoExpanderTemplateSettings), new PropertyMetadata(0.0));
|
|
public static readonly DependencyProperty NegativeContentHeightProperty = DependencyProperty.Register(nameof(NegativeContentHeight), typeof(double), typeof(WinoExpanderTemplateSettings), new PropertyMetadata(0.0));
|
|
|
|
public double NegativeContentHeight
|
|
{
|
|
get { return (double)GetValue(NegativeContentHeightProperty); }
|
|
set { SetValue(NegativeContentHeightProperty, value); }
|
|
}
|
|
|
|
public double HeaderHeight
|
|
{
|
|
get { return (double)GetValue(HeaderHeightProperty); }
|
|
set { SetValue(HeaderHeightProperty, value); }
|
|
}
|
|
|
|
public double ContentHeight
|
|
{
|
|
get { return (double)GetValue(ContentHeightProperty); }
|
|
set { SetValue(ContentHeightProperty, value); }
|
|
}
|
|
}
|
|
|
|
#endregion
|