Mercurial > silverbladetech
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 } |