6 changed files with 212 additions and 3 deletions
@ -0,0 +1,155 @@
@@ -0,0 +1,155 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.ComponentModel; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Controls.Primitives; |
||||
using System.Windows.Media; |
||||
using System.Diagnostics; |
||||
using ICSharpCode.WpfDesign.Designer.Controls; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.ThumbnailView |
||||
{ |
||||
public class ThumbnailView : Control, INotifyPropertyChanged |
||||
{ |
||||
public DesignSurface DesignSurface |
||||
{ |
||||
get { return (DesignSurface)GetValue(DesignSurfaceProperty); } |
||||
set { SetValue(DesignSurfaceProperty, value); } |
||||
} |
||||
|
||||
public static readonly DependencyProperty DesignSurfaceProperty = |
||||
DependencyProperty.Register("DesignSurface", typeof(DesignSurface), typeof(ThumbnailView), new PropertyMetadata(OnDesignSurfaceChanged)); |
||||
|
||||
private static void OnDesignSurfaceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
{ |
||||
var ctl = d as ThumbnailView; |
||||
|
||||
|
||||
if (ctl.oldSurface != null) |
||||
ctl.oldSurface.LayoutUpdated -= ctl.DesignSurface_LayoutUpdated; |
||||
|
||||
ctl.oldSurface = ctl.DesignSurface; |
||||
ctl.scrollViewer = null; |
||||
|
||||
if (ctl.DesignSurface != null) |
||||
{ |
||||
ctl.DesignSurface.LayoutUpdated += ctl.DesignSurface_LayoutUpdated; |
||||
} |
||||
|
||||
ctl.OnPropertyChanged("ScrollViewer"); |
||||
} |
||||
|
||||
static ThumbnailView() |
||||
{ |
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ThumbnailView), new FrameworkPropertyMetadata(typeof(ThumbnailView))); |
||||
} |
||||
|
||||
public ScrollViewer ScrollViewer |
||||
{ |
||||
get |
||||
{ |
||||
if (DesignSurface != null && scrollViewer == null) |
||||
scrollViewer = DesignSurface.TryFindChild<ZoomControl>(); |
||||
|
||||
return scrollViewer; |
||||
} |
||||
} |
||||
|
||||
|
||||
void DesignSurface_LayoutUpdated(object sender, EventArgs e) |
||||
{ |
||||
if (this.scrollViewer == null) |
||||
OnPropertyChanged("ScrollViewer"); |
||||
|
||||
if (this.scrollViewer != null) |
||||
{ |
||||
double scale, xOffset, yOffset; |
||||
this.InvalidateScale(out scale, out xOffset, out yOffset); |
||||
|
||||
this.zoomThumb.Width = scrollViewer.ViewportWidth * scale; |
||||
this.zoomThumb.Height = scrollViewer.ViewportHeight * scale; |
||||
|
||||
Canvas.SetLeft(this.zoomThumb, xOffset + this.ScrollViewer.HorizontalOffset*scale); |
||||
Canvas.SetTop(this.zoomThumb, yOffset + this.ScrollViewer.VerticalOffset*scale); |
||||
} |
||||
} |
||||
|
||||
private DesignSurface oldSurface; |
||||
private ZoomControl scrollViewer; |
||||
private Canvas zoomCanvas; |
||||
private Thumb zoomThumb; |
||||
|
||||
public override void OnApplyTemplate() |
||||
{ |
||||
base.OnApplyTemplate(); |
||||
|
||||
this.zoomThumb = Template.FindName("PART_ZoomThumb", this) as Thumb; |
||||
this.zoomCanvas = Template.FindName("PART_ZoomCanvas", this) as Canvas; |
||||
|
||||
this.zoomThumb.DragDelta += this.Thumb_DragDelta; |
||||
|
||||
|
||||
} |
||||
|
||||
private void Thumb_DragDelta(object sender, DragDeltaEventArgs e) |
||||
{ |
||||
if (DesignSurface != null) |
||||
{ |
||||
if (scrollViewer != null) |
||||
{ |
||||
double scale, xOffset, yOffset; |
||||
this.InvalidateScale(out scale, out xOffset, out yOffset); |
||||
|
||||
scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + e.HorizontalChange / scale); |
||||
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + e.VerticalChange / scale); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void InvalidateScale(out double scale, out double xOffset, out double yOffset) |
||||
{ |
||||
var designedElement = this.DesignSurface.DesignContext.RootItem.Component as FrameworkElement; |
||||
|
||||
var fac1 = designedElement.ActualWidth / zoomCanvas.ActualWidth; |
||||
var fac2 = designedElement.ActualHeight / zoomCanvas.ActualHeight; |
||||
|
||||
// zoom canvas size
|
||||
double x = this.zoomCanvas.ActualWidth; |
||||
double y = this.zoomCanvas.ActualHeight; |
||||
|
||||
if (fac1 < fac2) |
||||
{ |
||||
x = designedElement.ActualWidth / fac2; |
||||
xOffset = (zoomCanvas.ActualWidth - x) / 2; |
||||
yOffset = 0; |
||||
} |
||||
else |
||||
{ |
||||
y = designedElement.ActualHeight / fac1; |
||||
xOffset = 0; |
||||
yOffset = (zoomCanvas.ActualHeight - y) / 2; |
||||
} |
||||
|
||||
double w = designedElement.ActualWidth; |
||||
double h = designedElement.ActualHeight; |
||||
|
||||
double scaleX = x / w; |
||||
double scaleY = y / h; |
||||
|
||||
scale = (scaleX < scaleY) ? scaleX : scaleY; |
||||
|
||||
xOffset += (x - scale * w) / 2; |
||||
yOffset += (y - scale * h) / 2; |
||||
} |
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged; |
||||
protected virtual void OnPropertyChanged(string propertyName) |
||||
{ |
||||
PropertyChangedEventHandler handler = PropertyChanged; |
||||
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
xmlns:thumbnailView="clr-namespace:ICSharpCode.WpfDesign.Designer.ThumbnailView"> |
||||
|
||||
<Style TargetType="{x:Type thumbnailView:ThumbnailView}"> |
||||
<Setter Property="SnapsToDevicePixels" Value="true" /> |
||||
<Setter Property="HorizontalAlignment" Value="Stretch" /> |
||||
<Setter Property="VerticalAlignment" Value="Stretch" /> |
||||
<Setter Property="Padding" Value="5" /> |
||||
<Setter Property="Template"> |
||||
<Setter.Value> |
||||
<ControlTemplate TargetType="{x:Type thumbnailView:ThumbnailView}"> |
||||
<Border CornerRadius="1" |
||||
ClipToBounds="True" |
||||
BorderThickness="1" |
||||
Background="#EEE" |
||||
BorderBrush="DimGray"> |
||||
<Grid> |
||||
<Canvas Margin="{TemplateBinding Padding}" Name="PART_ZoomCanvas"> |
||||
<Canvas.Background> |
||||
<VisualBrush Stretch="Uniform" Visual="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ScrollViewer.Content}" /> |
||||
</Canvas.Background> |
||||
<Thumb Name="PART_ZoomThumb" Cursor="SizeAll"> |
||||
<Thumb.Style> |
||||
<Style TargetType="Thumb"> |
||||
<Setter Property="Template"> |
||||
<Setter.Value> |
||||
<ControlTemplate TargetType="Thumb"> |
||||
<Rectangle StrokeThickness="1" Stroke="Black" Fill="Transparent" /> |
||||
</ControlTemplate> |
||||
</Setter.Value> |
||||
</Setter> |
||||
</Style> |
||||
</Thumb.Style> |
||||
</Thumb> |
||||
</Canvas> |
||||
</Grid> |
||||
</Border> |
||||
</ControlTemplate> |
||||
</Setter.Value> |
||||
</Setter> |
||||
</Style> |
||||
</ResourceDictionary> |
Loading…
Reference in new issue