1
1
// ReSharper disable once CheckNamespace
2
2
namespace Fluent
3
3
{
4
- using System ;
5
- using System . Diagnostics ;
6
4
using System . Windows ;
7
5
using System . Windows . Controls ;
8
6
using System . Windows . Media ;
9
- using Fluent . Extensions ;
10
- using Fluent . Internal ;
11
7
using Fluent . Internal . KnownBoxes ;
12
8
13
9
/// <summary>
14
10
/// Represents container of grouped gallery items in GalleryPanel or Gallery
15
11
/// </summary>
16
12
public class GalleryGroupContainer : HeaderedItemsControl
17
13
{
18
- #region Fields
19
-
20
- private int previousItemsCount ;
21
-
22
- // Whether MinWidth/MaxWidth of the ItemsPanel needs to be updated
23
- private bool minMaxWidthNeedsToBeUpdated = true ;
24
- private Panel itemsPanel ;
25
- private FrameworkElement targetForSizeConstraints ;
26
-
27
- #endregion
28
-
29
14
#region Properites
30
15
31
16
#region IsHeadered
@@ -127,12 +112,7 @@ public int MinItemsInRow
127
112
/// </summary>
128
113
public static readonly DependencyProperty MinItemsInRowProperty =
129
114
DependencyProperty . Register ( nameof ( MinItemsInRow ) , typeof ( int ) ,
130
- typeof ( GalleryGroupContainer ) , new FrameworkPropertyMetadata ( IntBoxes . Zero , FrameworkPropertyMetadataOptions . AffectsMeasure , OnMinItemsInRowChanged ) ) ;
131
-
132
- private static void OnMinItemsInRowChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
133
- {
134
- OnMaxOrMinItemsInRowChanged ( d , e ) ;
135
- }
115
+ typeof ( GalleryGroupContainer ) , new FrameworkPropertyMetadata ( IntBoxes . Zero , FrameworkPropertyMetadataOptions . AffectsMeasure ) ) ;
136
116
137
117
#endregion
138
118
@@ -150,35 +130,14 @@ public int MaxItemsInRow
150
130
/// <summary>
151
131
/// <see cref="DependencyProperty"/> for <see cref="MaxItemsInRow"/>.
152
132
/// </summary>
153
- public static readonly DependencyProperty MaxItemsInRowProperty = DependencyProperty . Register ( nameof ( MaxItemsInRow ) , typeof ( int ) , typeof ( GalleryGroupContainer ) , new FrameworkPropertyMetadata ( 0 , FrameworkPropertyMetadataOptions . AffectsMeasure , OnMaxItemsInRowChanged ) ) ;
154
-
155
- private static void OnMaxItemsInRowChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
156
- {
157
- OnMaxOrMinItemsInRowChanged ( d , e ) ;
158
- }
133
+ public static readonly DependencyProperty MaxItemsInRowProperty = DependencyProperty . Register ( nameof ( MaxItemsInRow ) , typeof ( int ) , typeof ( GalleryGroupContainer ) , new FrameworkPropertyMetadata ( 0 , FrameworkPropertyMetadataOptions . AffectsMeasure ) ) ;
159
134
160
135
#endregion
161
136
162
- private Panel RealItemsPanel => this . itemsPanel ?? ( this . itemsPanel = FindItemsPanel ( this ) ) ;
163
-
164
- private static void OnMaxOrMinItemsInRowChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
165
- {
166
- var galleryGroupContainer = ( GalleryGroupContainer ) d ;
167
- galleryGroupContainer . minMaxWidthNeedsToBeUpdated = true ;
168
- }
169
-
170
137
#endregion
171
138
172
139
#region Initialization
173
140
174
- /// <summary>
175
- /// Creates a new instance of <see cref="GalleryGroupContainer"/>.
176
- /// </summary>
177
- public GalleryGroupContainer ( )
178
- {
179
- this . Unloaded += this . HandleUnloaded ;
180
- }
181
-
182
141
/// <summary>
183
142
/// Static constructor
184
143
/// </summary>
@@ -192,163 +151,9 @@ protected override void OnItemsPanelChanged(ItemsPanelTemplate oldItemsPanel, It
192
151
{
193
152
base . OnItemsPanelChanged ( oldItemsPanel , newItemsPanel ) ;
194
153
195
- this . itemsPanel = null ;
196
- this . minMaxWidthNeedsToBeUpdated = true ;
197
- this . InvalidateMeasure ( ) ;
198
- }
199
-
200
- #endregion
201
-
202
- #region MaxWidth Updating
203
-
204
- // Sets MaxWidth of the items panel based of ItemsInRow property
205
- private void UpdateMinAndMaxWidth ( Size constraint )
206
- {
207
- if ( this . minMaxWidthNeedsToBeUpdated == false )
208
- {
209
- return ;
210
- }
211
-
212
- if ( this . RealItemsPanel == null )
213
- {
214
- // Item's panel is not ready now
215
- if ( this . IsLoaded )
216
- {
217
- Debug . WriteLine ( "Panel with IsItemsHost = true is not found in GalleryGroupContainer (probably the style is not correct or haven't attached yet)" ) ;
218
- }
219
- else
220
- {
221
- // Prevent duplicate registration
222
- this . Loaded -= this . HandleLoaded ;
223
- this . Loaded += this . HandleLoaded ;
224
- }
225
-
226
- return ;
227
- }
228
-
229
- this . minMaxWidthNeedsToBeUpdated = false ;
230
-
231
- // Issue references:
232
- // - #542 + commit https://github.com/fluentribbon/Fluent.Ribbon/commit/8b458b1cfc5e440f54778c808142fffa67a23978
233
- // - #666
234
- // We need to check if we are inside a closed InRibbonGallery.
235
- // - If we are inside an closed InRibbonGallery we need to restrict the size of "this"
236
- // - If we are inside an opened InRibbonGallery or not inside an InRibbonGallery we need to restrict the size of "RealItemsPanel"
237
- var inRibbonGallery = UIHelper . GetParent < InRibbonGallery > ( this ) ;
238
- var isInsideClosedInRibbonGallery = inRibbonGallery != null && inRibbonGallery . IsDropDownOpen == false ;
239
- this . targetForSizeConstraints = isInsideClosedInRibbonGallery ? ( FrameworkElement ) this : this . RealItemsPanel ;
240
-
241
- var nonTargetForSizeConstraints = isInsideClosedInRibbonGallery ? ( FrameworkElement ) this . RealItemsPanel : this ;
242
-
243
- nonTargetForSizeConstraints . MinWidth = 0 ;
244
- nonTargetForSizeConstraints . MaxWidth = double . PositiveInfinity ;
245
-
246
- if ( this . Orientation == Orientation . Vertical )
247
- {
248
- // Min/Max is used for Horizontal layout only
249
- this . targetForSizeConstraints . MinWidth = 0 ;
250
- this . targetForSizeConstraints . MaxWidth = double . PositiveInfinity ;
251
- return ;
252
- }
253
-
254
- var itemWidth = this . GetItemSize ( ) . Width ;
255
- if ( double . IsNaN ( itemWidth ) )
256
- {
257
- // We can't calc item's width now
258
- return ;
259
- }
260
-
261
- this . targetForSizeConstraints . MinWidth = ( Math . Min ( this . Items . Count , this . MinItemsInRow ) * itemWidth ) + 0.1 ;
262
- this . targetForSizeConstraints . MaxWidth = this . MaxItemsInRow == 0
263
- ? constraint . Width
264
- : ( Math . Min ( this . Items . Count , this . MaxItemsInRow ) * itemWidth ) + 0.1 ;
265
- }
266
-
267
- private void HandleLoaded ( object sender , RoutedEventArgs e )
268
- {
269
- this . Loaded -= this . HandleLoaded ;
270
-
271
- if ( this . minMaxWidthNeedsToBeUpdated == false )
272
- {
273
- return ;
274
- }
275
-
276
154
this . InvalidateMeasure ( ) ;
277
155
}
278
156
279
- private void HandleUnloaded ( object sender , RoutedEventArgs e )
280
- {
281
- this . itemsPanel = null ;
282
-
283
- this . minMaxWidthNeedsToBeUpdated = true ;
284
- }
285
-
286
- /// <summary>
287
- /// Determines the desired item size.
288
- /// </summary>
289
- /// <returns>
290
- /// <see cref="Size"/> constructed from <see cref="ItemWidth"/> and <see cref="ItemHeight"/>.
291
- /// If no items are present <see cref="Size.Empty"/>.
292
- /// </returns>
293
- public Size GetItemSize ( )
294
- {
295
- if ( this . Items . Count == 0 )
296
- {
297
- return Size . Empty ;
298
- }
299
-
300
- return new Size ( this . ItemWidth , this . ItemHeight ) ;
301
- }
302
-
303
- // Finds panel with IsItemsHost, or null if such panel is not found
304
- private static Panel FindItemsPanel ( DependencyObject obj )
305
- {
306
- for ( var i = 0 ; i < VisualTreeHelper . GetChildrenCount ( obj ) ; i ++ )
307
- {
308
- if ( obj is Panel panel &&
309
- panel . IsItemsHost )
310
- {
311
- return panel ;
312
- }
313
-
314
- panel = FindItemsPanel ( VisualTreeHelper . GetChild ( obj , i ) ) ;
315
- if ( panel != null )
316
- {
317
- return panel ;
318
- }
319
- }
320
-
321
- return null ;
322
- }
323
-
324
157
#endregion
325
-
326
- /// <inheritdoc />
327
- protected override Size MeasureOverride ( Size constraint )
328
- {
329
- if ( this . previousItemsCount != this . Items . Count
330
- || this . minMaxWidthNeedsToBeUpdated )
331
- {
332
- // Track ItemsPanel changes
333
- this . previousItemsCount = this . Items . Count ;
334
- this . minMaxWidthNeedsToBeUpdated = true ;
335
-
336
- this . UpdateMinAndMaxWidth ( constraint ) ;
337
- }
338
-
339
- if ( this . targetForSizeConstraints != null )
340
- {
341
- return base . MeasureOverride ( new Size ( this . targetForSizeConstraints . MaxWidth , constraint . Height ) ) ;
342
- }
343
-
344
- return base . MeasureOverride ( constraint ) ;
345
- // todo: maybe the following code is a better alternative
346
- //if (this.targetForSizeConstraints != null)
347
- //{
348
- // return base.MeasureOverride(new Size(Math.Min(constraint.Width, this.targetForSizeConstraints.MaxWidth), constraint.Height));
349
- //}
350
-
351
- //return Size.Empty;
352
- }
353
158
}
354
159
}
0 commit comments