Skip to content

Commit 5420874

Browse files
committed
Adding control width trigger
1 parent 2c04c96 commit 5420874

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using Windows.UI.Xaml;
6+
7+
namespace Microsoft.Toolkit.Uwp.UI.Triggers
8+
{
9+
/// <summary>
10+
/// A conditional state trigger that functions
11+
/// based on the target control's width.
12+
/// </summary>
13+
public class ControlWidthTrigger : StateTriggerBase
14+
{
15+
/// <summary>
16+
/// Gets or sets a value indicating
17+
/// whether this trigger will be active or not.
18+
/// </summary>
19+
public bool CanTrigger
20+
{
21+
get => (bool)GetValue(CanTriggerProperty);
22+
set => SetValue(CanTriggerProperty, value);
23+
}
24+
25+
/// <summary>
26+
/// Identifies the <see cref="CanTrigger"/> DependencyProperty.
27+
/// </summary>
28+
public static readonly DependencyProperty CanTriggerProperty = DependencyProperty.Register(
29+
nameof(CanTrigger),
30+
typeof(bool),
31+
typeof(ControlWidthTrigger),
32+
new PropertyMetadata(true, OnCanTriggerProperty));
33+
34+
private static void OnCanTriggerProperty(DependencyObject d, DependencyPropertyChangedEventArgs e)
35+
{
36+
((ControlWidthTrigger)d).UpdateTrigger();
37+
}
38+
39+
/// <summary>
40+
/// Gets or sets the max size at which to trigger.
41+
/// </summary>
42+
public double MaxWidth
43+
{
44+
get => (double)GetValue(MaxWidthProperty);
45+
set => SetValue(MaxWidthProperty, value);
46+
}
47+
48+
/// <summary>
49+
/// Identifies the <see cref="MaxWidth"/> DependencyProperty.
50+
/// </summary>
51+
public static readonly DependencyProperty MaxWidthProperty = DependencyProperty.Register(
52+
nameof(MaxWidth),
53+
typeof(double),
54+
typeof(ControlWidthTrigger),
55+
new PropertyMetadata(double.PositiveInfinity, OnMaxWidthPropertyChanged));
56+
57+
private static void OnMaxWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
58+
{
59+
((ControlWidthTrigger)d).UpdateTrigger();
60+
}
61+
62+
/// <summary>
63+
/// Gets or sets the min size at which to trigger.
64+
/// </summary>
65+
public double MinWidth
66+
{
67+
get => (double)GetValue(MinWidthProperty);
68+
set => SetValue(MinWidthProperty, value);
69+
}
70+
71+
/// <summary>
72+
/// Identifies the <see cref="MinWidth"/> DependencyProperty.
73+
/// </summary>
74+
public static readonly DependencyProperty MinWidthProperty = DependencyProperty.Register(
75+
nameof(MinWidth),
76+
typeof(double),
77+
typeof(ControlWidthTrigger),
78+
new PropertyMetadata(0.0, OnMinWidthPropertyChanged));
79+
80+
private static void OnMinWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
81+
{
82+
((ControlWidthTrigger)d).UpdateTrigger();
83+
}
84+
85+
/// <summary>
86+
/// Gets or sets the element whose width will observed
87+
/// for the trigger.
88+
/// </summary>
89+
public FrameworkElement TargetElement
90+
{
91+
get => (FrameworkElement)GetValue(TargetElementProperty);
92+
set => SetValue(TargetElementProperty, value);
93+
}
94+
95+
/// <summary>
96+
/// Identifies the <see cref="TargetElement"/> DependencyProperty.
97+
/// </summary>
98+
/// <remarks>
99+
/// Using a DependencyProperty as the backing store for TargetElement. This enables animation, styling, binding, etc.
100+
/// </remarks>
101+
public static readonly DependencyProperty TargetElementProperty = DependencyProperty.Register(
102+
nameof(TargetElement),
103+
typeof(FrameworkElement),
104+
typeof(ControlWidthTrigger),
105+
new PropertyMetadata(null, OnTargetElementPropertyChanged));
106+
107+
private static void OnTargetElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
108+
{
109+
((ControlWidthTrigger)d).UpdateTargetElement((FrameworkElement)e.OldValue, (FrameworkElement)e.NewValue);
110+
}
111+
112+
// Handle event to get current values
113+
private void OnTargetElementSizeChanged(object sender, SizeChangedEventArgs e)
114+
{
115+
UpdateTrigger();
116+
}
117+
118+
private void UpdateTargetElement(FrameworkElement oldValue, FrameworkElement newValue)
119+
{
120+
if (oldValue != null)
121+
{
122+
oldValue.SizeChanged -= OnTargetElementSizeChanged;
123+
}
124+
125+
if (newValue != null)
126+
{
127+
newValue.SizeChanged += OnTargetElementSizeChanged;
128+
}
129+
130+
UpdateTrigger();
131+
}
132+
133+
// Logic to evaluate and apply trigger value
134+
private void UpdateTrigger()
135+
{
136+
if (TargetElement == null || !CanTrigger)
137+
{
138+
SetActive(false);
139+
return;
140+
}
141+
142+
SetActive(MinWidth <= TargetElement.ActualWidth && TargetElement.ActualWidth < MaxWidth);
143+
}
144+
}
145+
}

0 commit comments

Comments
 (0)