comparison Chronosv2/source/Presentation/Controls/SplitButton.cs @ 10:443821e55f06

Initial cleaned up add from Codeplex files
author stevenh7776 stevenhollidge@hotmail.com
date Tue, 21 Feb 2012 17:25:44 +0700
parents
children 09d18d6e5f40
comparison
equal deleted inserted replaced
9:904a9faadf8b 10:443821e55f06
1 /*
2 The MIT License
3
4 Copyright (c) 2009-2010. Carlos Guzmán Álvarez. http://chronoswpf.codeplex.com/
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23 */
24
25 using System.ComponentModel;
26 using System.Windows;
27 using System.Windows.Controls;
28 using System.Windows.Controls.Primitives;
29 using System.Windows.Markup;
30
31 namespace Chronos.Presentation.Controls
32 {
33 /// <summary>
34 /// Implemetation of a Split Button
35 /// </summary>
36 [ContentProperty("Items")]
37 [DefaultProperty("Items")]
38 public partial class SplitButton
39 : Button
40 {
41 #region · Dependency Properties ·
42
43 // AddOwner Dependency properties
44 public static readonly DependencyProperty IsContextMenuOpenProperty =
45 DependencyProperty.Register(
46 "IsContextMenuOpen",
47 typeof(bool),
48 typeof(SplitButton),
49 new FrameworkPropertyMetadata(false,
50 new PropertyChangedCallback(OnIsContextMenuOpenChanged)));
51
52 public static readonly DependencyProperty PlacementProperty =
53 ContextMenuService.PlacementProperty.AddOwner(
54 typeof(SplitButton),
55 new FrameworkPropertyMetadata(PlacementMode.Bottom,
56 new PropertyChangedCallback(OnPlacementChanged)));
57
58 public static readonly DependencyProperty PlacementRectangleProperty =
59 ContextMenuService.PlacementRectangleProperty.AddOwner(
60 typeof(SplitButton),
61 new FrameworkPropertyMetadata(Rect.Empty,
62 new PropertyChangedCallback(OnPlacementRectangleChanged)));
63
64 public static readonly DependencyProperty HorizontalOffsetProperty =
65 ContextMenuService.HorizontalOffsetProperty.AddOwner(
66 typeof(SplitButton),
67 new FrameworkPropertyMetadata(0.0,
68 new PropertyChangedCallback(OnHorizontalOffsetChanged)));
69
70 public static readonly DependencyProperty VerticalOffsetProperty =
71 ContextMenuService.VerticalOffsetProperty.AddOwner(
72 typeof(SplitButton),
73 new FrameworkPropertyMetadata(0.0,
74 new PropertyChangedCallback(OnVerticalOffsetChanged)));
75
76 #endregion
77
78 #region · Dependency Properties Callbacks ·
79
80 private static void OnIsContextMenuOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
81 {
82 SplitButton s = (SplitButton)d;
83 s.EnsureContextMenuIsValid();
84
85 if (!s.ContextMenu.HasItems)
86 {
87 return;
88 }
89
90 bool value = (bool)e.NewValue;
91
92 if (value && !s.ContextMenu.IsOpen)
93 {
94 s.ContextMenu.IsOpen = true;
95 }
96 else if (!value && s.ContextMenu.IsOpen)
97 {
98 s.ContextMenu.IsOpen = false;
99 }
100 }
101
102 /// <summary>
103 /// Placement Property changed callback, pass the value through to the buttons context menu
104 /// </summary>
105 private static void OnPlacementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
106 {
107 SplitButton s = d as SplitButton;
108
109 if (s == null)
110 {
111 return;
112 }
113
114 s.EnsureContextMenuIsValid();
115 s.ContextMenu.Placement = (PlacementMode)e.NewValue;
116 }
117
118 /// <summary>
119 /// PlacementRectangle Property changed callback, pass the value through to the buttons context menu
120 /// </summary>
121 private static void OnPlacementRectangleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
122 {
123 SplitButton s = d as SplitButton;
124
125 if (s == null)
126 {
127 return;
128 }
129
130 s.EnsureContextMenuIsValid();
131 s.ContextMenu.PlacementRectangle = (Rect)e.NewValue;
132 }
133
134 /// <summary>
135 /// HorizontalOffset Property changed callback, pass the value through to the buttons context menu
136 /// </summary>
137 private static void OnHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
138 {
139 SplitButton s = d as SplitButton;
140
141 if (s == null)
142 {
143 return;
144 }
145
146 s.EnsureContextMenuIsValid();
147 s.ContextMenu.HorizontalOffset = (double)e.NewValue;
148 }
149
150 /// <summary>
151 /// VerticalOffset Property changed callback, pass the value through to the buttons context menu
152 /// </summary>
153 private static void OnVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
154 {
155 SplitButton s = d as SplitButton;
156 if (s == null)
157 {
158 return;
159 }
160
161 s.EnsureContextMenuIsValid();
162 s.ContextMenu.VerticalOffset = (double)e.NewValue;
163 }
164
165 #endregion
166
167 #region · Static Constructor ·
168
169 /// <summary>
170 /// Static Constructor
171 /// </summary>
172 static SplitButton()
173 {
174 DefaultStyleKeyProperty.OverrideMetadata(
175 typeof(SplitButton),
176 new FrameworkPropertyMetadata(typeof(SplitButton)));
177 }
178
179 #endregion
180
181 #region · Properties ·
182
183 /// <summary>
184 /// The Split Button's Items property maps to the base classes ContextMenu.Items property
185 /// </summary>
186 public ItemCollection Items
187 {
188 get
189 {
190 this.EnsureContextMenuIsValid();
191
192 return this.ContextMenu.Items;
193 }
194 }
195
196 /// <summary>
197 /// Gets or sets the IsContextMenuOpen property.
198 /// </summary>
199 public bool IsContextMenuOpen
200 {
201 get { return (bool)GetValue(IsContextMenuOpenProperty); }
202 set { SetValue(IsContextMenuOpenProperty, value); }
203 }
204
205 /// <summary>
206 /// Placement of the Context menu
207 /// </summary>
208 public PlacementMode Placement
209 {
210 get { return (PlacementMode)GetValue(PlacementProperty); }
211 set { SetValue(PlacementProperty, value); }
212 }
213
214 /// <summary>
215 /// PlacementRectangle of the Context menu
216 /// </summary>
217 public Rect PlacementRectangle
218 {
219 get { return (Rect)GetValue(PlacementRectangleProperty); }
220 set { SetValue(PlacementRectangleProperty, value); }
221 }
222
223 /// <summary>
224 /// HorizontalOffset of the Context menu
225 /// </summary>
226 public double HorizontalOffset
227 {
228 get { return (double)GetValue(HorizontalOffsetProperty); }
229 set { SetValue(HorizontalOffsetProperty, value); }
230 }
231
232 /// <summary>
233 /// VerticalOffset of the Context menu
234 /// </summary>
235 public double VerticalOffset
236 {
237 get { return (double)GetValue(VerticalOffsetProperty); }
238 set { SetValue(VerticalOffsetProperty, value); }
239 }
240
241 #endregion
242
243 #region · Constructors ·
244
245 public SplitButton()
246 : base()
247 {
248 }
249
250 #endregion
251
252 #region · Overriden Methods ·
253
254 /// <summary>
255 /// Handles the Base Buttons OnClick event
256 /// </summary>
257 protected override void OnClick()
258 {
259 this.OnDropdown();
260 }
261
262 #endregion
263
264 #region · Private Methods ·
265
266 /// <summary>
267 /// Make sure the Context menu is not null
268 /// </summary>
269 private void EnsureContextMenuIsValid()
270 {
271 if (this.ContextMenu == null)
272 {
273 this.ContextMenu = new ContextMenu();
274 this.ContextMenu.PlacementTarget = this;
275 this.ContextMenu.Placement = this.Placement;
276
277 this.ContextMenu.Opened += ((sender, routedEventArgs) => IsContextMenuOpen = true);
278 this.ContextMenu.Closed += ((sender, routedEventArgs) => IsContextMenuOpen = false);
279 }
280 }
281
282 private void OnDropdown()
283 {
284 this.EnsureContextMenuIsValid();
285
286 if (!this.ContextMenu.HasItems)
287 {
288 return;
289 }
290
291 this.ContextMenu.IsOpen = !IsContextMenuOpen; // open it if closed, close it if open
292 }
293
294 #endregion
295 }
296 }