Элемент управления масштабированием, найденный на http://wpfextensions.codeplex.com/, - это то, что я хотел бы использовать в своем проекте. Однако есть одна особенность, которую я хотел бы иметь. Я хотел бы, чтобы он работал с ScrollViewer, чтобы при увеличении содержимого активировались полосы прокрутки (при необходимости).
Шаблон элемента управления определен в Generic.xaml:
<Style TargetType="{x:Type Controls:ZoomControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:ZoomControl}">
<Grid>
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="Green"
ClipToBounds="{TemplateBinding ClipToBounds}">
<Controls:ZoomContentPresenter x:Name="PART_Presenter"
ClipToBounds="False" />
</Border>
<Canvas>
<!-- Controls -->
<Border Padding="5"
CornerRadius="5"
Background="#88C0C0C0"
Canvas.Left="20"
Canvas.Top="20"
ToolTipService.InitialShowDelay="0">
<Border.ToolTip>
<StackPanel Orientation="Vertical">
<TextBlock><Run FontWeight="Bold">CTRL + Wheel:</Run> Zoom In / Out</TextBlock>
<TextBlock><Run FontWeight="Bold">ALT + Drag:</Run> ZoomBox</TextBlock>
<TextBlock><Run FontWeight="Bold">(SHIFT +) Drag:</Run> Pan</TextBlock>
</StackPanel>
</Border.ToolTip>
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<Style TargetType="{x:Type RadioButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Border x:Name="border"
BorderBrush="Black"
Background="Silver"
BorderThickness="1"
CornerRadius="5"
Width="40"
Height="40"
Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="border"
Property="Background"
Value="WhiteSmoke" />
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="border"
Property="Background"
Value="DarkGray" />
<Setter TargetName="border"
Property="TextBlock.FontWeight"
Value="Bold" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<Slider Height="150"
Minimum="{TemplateBinding MinZoom,Converter={StaticResource log10Converter}}"
Maximum="{TemplateBinding MaxZoom,Converter={StaticResource log10Converter}}"
Value="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Zoom,Mode=TwoWay,Converter={StaticResource log10Converter}}"
HorizontalAlignment="Center"
Ticks="0.1, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2"
AutoToolTipPlacement="BottomRight"
AutoToolTipPrecision="1"
TickPlacement="BottomRight"
TickFrequency="1"
LargeChange="1"
SmallChange="0.1"
Orientation="Vertical" />
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Zoom,StringFormat='{}{0:F2}x'}"
HorizontalAlignment="Center"
FontWeight="Bold" />
<RadioButton Content="1:1"
GroupName="rbgZoomMode"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Mode,Converter={StaticResource equalityConverter},ConverterParameter={x:Static Controls:ZoomControlModes.Original}}" />
<RadioButton Content="Fill"
GroupName="rbgZoomMode"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Mode,Converter={StaticResource equalityConverter},ConverterParameter={x:Static Controls:ZoomControlModes.Fill}}" />
</StackPanel>
</Border>
<!-- ZoomBox -->
<Border BorderBrush="{TemplateBinding ZoomBoxBorderBrush}"
BorderThickness="{TemplateBinding ZoomBoxBorderThickness}"
Canvas.Left="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ZoomBox.X}"
Canvas.Top="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ZoomBox.Y}"
Opacity="{TemplateBinding ZoomBoxOpacity}"
Background="{TemplateBinding ZoomBoxBackground}"
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ZoomBox.Width}"
Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ZoomBox.Height}" />
</Canvas>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background"
Value="White" />
<Setter Property="ZoomBoxBackground">
<Setter.Value>
<LinearGradientBrush StartPoint="0.0, 0.0"
EndPoint="1.0, 1.0">
<GradientStop Color="Silver"
Offset="0.0" />
<GradientStop Color="DarkGray"
Offset="1.0" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="ZoomBoxBorderBrush"
Value="Black" />
<Setter Property="ZoomBoxBorderThickness"
Value="1" />
<Setter Property="ClipToBounds"
Value="True" />
<Style.Triggers>
<Trigger Property="ModifierMode"
Value="Pan">
<Setter Property="Cursor"
Value="SizeAll" />
</Trigger>
<Trigger Property="ModifierMode"
Value="ZoomBox">
<Setter Property="Cursor"
Value="Hand" />
</Trigger>
</Style.Triggers>
</Style>
Я попытался добавить теги ScrollViewer вокруг PART_Presenter, но это привело к повреждению элемента управления (ничего не отображалось).
Надеюсь, кто-нибудь умнее меня поможет мне с этим. Управление не такое сложное, но я все еще изучаю WPF и особенно шаблоны.
Большое спасибо.