7
7
8
8
namespace InteractionControls ;
9
9
10
+ [ TemplatePart ( Name = "PART_Grid" , Type = typeof ( Grid ) ) ]
10
11
[ TemplatePart ( Name = "PART_Presenter" , Type = typeof ( ContentPresenter ) ) ]
11
12
[ TemplatePart ( Name = "PART_scrollV" , Type = typeof ( ScrollBar ) ) ]
12
13
[ TemplatePart ( Name = "PART_scrollH" , Type = typeof ( ScrollBar ) ) ]
13
14
public partial class ZoomContentControl : ContentControl
14
15
{
16
+ private Grid ? _grid ;
15
17
private ContentPresenter ? _presenter ;
16
18
private ScrollBar ? _scrollV ;
17
19
private ScrollBar ? _scrollH ;
20
+ private Canvas _canvas = new Canvas ( ) ;
21
+
18
22
private bool IsAllowedToWork => ( IsEnabled && IsActive && _presenter is not null ) ;
19
23
20
24
public bool ResetWhenNotActive { get ; set ; } = true ;
@@ -157,16 +161,19 @@ public double VerticalMaxScroll
157
161
get => ( double ) GetValue ( VerticalMaxScrollProperty ) ;
158
162
set => SetValue ( VerticalMaxScrollProperty , value ) ;
159
163
}
164
+
160
165
public double VerticalMinScroll
161
166
{
162
167
get => ( double ) GetValue ( VerticalMinScrollProperty ) ;
163
168
set => SetValue ( VerticalMinScrollProperty , value ) ;
164
169
}
170
+
165
171
public double HorizontalMaxScroll
166
172
{
167
173
get => ( double ) GetValue ( HorizontalMaxScrollProperty ) ;
168
174
set => SetValue ( HorizontalMaxScrollProperty , value ) ;
169
175
}
176
+
170
177
public double HorizontalMinScroll
171
178
{
172
179
get => ( double ) GetValue ( HorizontalMinScrollProperty ) ;
@@ -190,6 +197,7 @@ public double ViewPortHeight
190
197
get => ( double ) GetValue ( ViewPortHeightProperty ) ;
191
198
set => SetValue ( ViewPortHeightProperty , value ) ;
192
199
}
200
+
193
201
public double ViewPortWidth
194
202
{
195
203
get => ( double ) GetValue ( ViewPortWidthProperty ) ;
@@ -205,7 +213,7 @@ private void RegisterPropertyHandlers()
205
213
RegisterPropertyChangedCallback ( MinZoomLevelProperty , CoerceZoomLevel ) ;
206
214
RegisterPropertyChangedCallback ( MaxZoomLevelProperty , CoerceZoomLevel ) ;
207
215
208
- RegisterPropertyChangedCallback ( ZoomLevelProperty , ( s , e ) => { UpdateScrollLimits ( ) ; } ) ;
216
+ RegisterPropertyChangedCallback ( ZoomLevelProperty , ( s , e ) => UpdateScrollLimits ( ) ) ;
209
217
210
218
RegisterPropertyChangedCallback ( HorizontalOffsetProperty , UpdateVerticalScrollBarValue ) ;
211
219
RegisterPropertyChangedCallback ( VerticalOffsetProperty , UpdateHorizontalScrollBarValue ) ;
@@ -234,6 +242,26 @@ private void IsActiveChanged(DependencyObject sender, DependencyProperty dp)
234
242
{
235
243
_scrollV . Visibility = IsActive ? Visibility . Visible : Visibility . Collapsed ;
236
244
}
245
+
246
+ if ( _grid is not null )
247
+ {
248
+ if ( IsActive )
249
+ {
250
+ _grid . Children . Remove ( _presenter ) ;
251
+ _grid . Children . Add ( _canvas ) ;
252
+ _canvas . Children . Add ( _presenter ) ;
253
+ Grid . SetRow ( _canvas , 0 ) ;
254
+ Grid . SetColumn ( _canvas , 0 ) ;
255
+ }
256
+ else
257
+ {
258
+ _canvas . Children . Remove ( _presenter ) ;
259
+ _grid . Children . Remove ( _canvas ) ;
260
+ _grid . Children . Add ( _presenter ) ;
261
+ Grid . SetRow ( _presenter , 0 ) ;
262
+ Grid . SetColumn ( _presenter , 0 ) ;
263
+ }
264
+ }
237
265
}
238
266
239
267
private void UpdateScrollLimits ( )
@@ -273,6 +301,7 @@ public ZoomContentControl()
273
301
274
302
protected override void OnApplyTemplate ( )
275
303
{
304
+ _grid = GetTemplateChild ( "PART_Grid" ) as Grid ;
276
305
_presenter = GetTemplateChild ( "PART_Presenter" ) as ContentPresenter ;
277
306
_scrollV = GetTemplateChild ( "PART_scrollV" ) as ScrollBar ;
278
307
_scrollH = GetTemplateChild ( "PART_scrollH" ) as ScrollBar ;
@@ -284,31 +313,26 @@ protected override void OnApplyTemplate()
284
313
RegisterPointerHandlers ( ) ;
285
314
}
286
315
#region ScrollBars Events
316
+
287
317
private void RegisterToControlEvents ( )
288
318
{
289
319
//due to templatebinding there's no TwoWay mode. We need to manually update the values
290
320
if ( _scrollV is not null )
291
321
{
292
- _scrollV . Scroll += _scrollV_Scroll ;
322
+ _scrollV . Scroll += ScrollV_Scroll ;
293
323
}
294
324
295
325
if ( _scrollH is not null )
296
326
{
297
- _scrollH . Scroll += _scrollH_Scroll ;
327
+ _scrollH . Scroll += ScrollH_Scroll ;
298
328
}
299
329
}
300
330
301
- private void _scrollV_Scroll ( object sender , ScrollEventArgs e )
302
- {
303
- //TemplateBinding doesn't support TwoWay mode. We need to manually update the values
304
- VerticalOffset = - 1 * e . NewValue ;
305
- }
331
+ //TemplateBinding doesn't support TwoWay mode. We need to manually update the values
332
+ private void ScrollV_Scroll ( object sender , ScrollEventArgs e ) => VerticalOffset = - 1 * e . NewValue ;
333
+
334
+ private void ScrollH_Scroll ( object sender , ScrollEventArgs e ) => HorizontalOffset = - 1 * e . NewValue ;
306
335
307
- private void _scrollH_Scroll ( object sender , ScrollEventArgs e )
308
- {
309
- //TemplateBinding doesn't support TwoWay mode. We need to manually update the values
310
- HorizontalOffset = - 1 * e . NewValue ;
311
- }
312
336
#endregion
313
337
314
338
private uint _capturedPointerId ;
@@ -390,7 +414,7 @@ private void OnPointerWheelChanged(object sender, PointerRoutedEventArgs e)
390
414
return ; // Don't handle the event when the control is disabled.
391
415
}
392
416
393
- var pointerPoint = e . GetCurrentPoint ( _presenter ) ;
417
+ var pointerPoint = e . GetCurrentPoint ( this ) ;
394
418
var pointerProperties = pointerPoint . Properties ;
395
419
var pointerPosition = pointerPoint . Position ;
396
420
@@ -410,14 +434,7 @@ private void OnPointerWheelChanged(object sender, PointerRoutedEventArgs e)
410
434
{
411
435
e . Handled = true ;
412
436
413
- var hzc = HorizontalZoomCenter ;
414
- var vzc = VerticalZoomCenter ;
415
- var newPointerPosX = ( ( pointerPosition . X - hzc ) * changeRatio ) + hzc ;
416
- var newPointerPosY = ( ( pointerPosition . Y - vzc ) * changeRatio ) + vzc ;
417
-
418
437
ZoomLevel *= changeRatio ;
419
- HorizontalOffset += newPointerPosX - pointerPosition . X ;
420
- VerticalOffset += newPointerPosY - pointerPosition . Y ;
421
438
HorizontalZoomCenter = pointerPosition . X ;
422
439
VerticalZoomCenter = pointerPosition . Y ;
423
440
return ;
@@ -451,4 +468,10 @@ public void ResetOffset()
451
468
HorizontalOffset = 0 ;
452
469
VerticalOffset = 0 ;
453
470
}
471
+
472
+ public void Centralize ( )
473
+ {
474
+ HorizontalOffset = ( ActualWidth / 2 ) - ( ViewPortWidth / 2 ) ;
475
+ VerticalOffset = ( ActualHeight / 2 ) - ( ViewPortHeight / 2 ) ;
476
+ }
454
477
}
0 commit comments