可拖拽面板的WPF实现

 

这里要实现的功能,就是类似Blend中间的工作面板——可以缩放和拖动其中的内容。

这个功能的实现方式应该有不少。而且在Blend 3当中加入了MouseDragElementBehavior,这个功能的实现似乎就更简单了,但是MouseDragElementBehavior是基于RenderTransform来实现拖动的效果的。结果就是滚动条不能正确地显示出来。

下面给出了一个相对比较简单的解决方案,用一个CustomControl实现了缩放和拖拽功能,同时滚动条也能正常显示。

 

代码如下:

DesignViewer
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace DesignView
{
    
/// <summary>
    
/// 
    
/// </summary>
    public class DesignViewer : ContentControl
    {
        
#region Private Fields

        
private Thickness beginMargin;
        
private Viewbox viewbox;

        
#endregion

        
#region Constructors

        
static DesignViewer()
        {
            DefaultStyleKeyProperty.OverrideMetadata(
typeof(DesignViewer), new FrameworkPropertyMetadata(typeof(DesignViewer)));
        }

        
#endregion

        
#region Event Handlers

        
public override void OnApplyTemplate()
        {
            
base.OnApplyTemplate();
            viewbox 
= Template.FindName("PART_Viewbox"thisas Viewbox;
            Thumb thumb 
= Template.FindName("PART_Thumb"thisas Thumb;

            
if (viewbox != null)
            {
                viewbox.PreviewMouseLeftButtonDown 
+= OnThumbPreviewMouseLeftButtonDown;
            }

            
if (thumb != null)
            {
                thumb.DragDelta 
+= OnDragDelta;
                thumb.DragStarted 
+= OnDragStarted;
            }
        }

        
private void OnThumbPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled 
= true;
        }

        
private void OnDragDelta(object sender, DragDeltaEventArgs e)
        {
            viewbox.Margin 
= new Thickness()
            {
                Top 
= beginMargin.Top + e.VerticalChange * 2,
                Left 
= beginMargin.Left + e.HorizontalChange * 2
            };
        }

        
private void OnDragStarted(object sender, DragStartedEventArgs e)
        {
            beginMargin 
= viewbox.Margin;
        }

        
#endregion
    }
}

Style如下所示: 

 

Design Viewer Style
<ResourceDictionary
  
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local
="clr-namespace:DesignView">
  
<Style x:Key="DragThumbStyle"
         TargetType
="{x:Type Thumb}">
    
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
    
<Setter Property="Template">
      
<Setter.Value>
        
<ControlTemplate TargetType="{x:Type Thumb}">
          
<Border Background="#00000000"/>
        
</ControlTemplate>
      
</Setter.Value>
    
</Setter>
  
</Style>

  
<ControlTemplate x:Key="DesignViewerTemplate"
                   TargetType
="{x:Type local:DesignViewer}">
    
<DockPanel>
      
<Slider x:Name="slider"
              Value
="1" Maximum="25"
              DockPanel.Dock
="Top"/>
      
<ScrollViewer VerticalScrollBarVisibility="Auto"
                    HorizontalScrollBarVisibility
="Auto">
        
<Grid>
          
<Thumb x:Name="PART_Thumb"
                 Style
="{StaticResource DragThumbStyle}"/>
          
<Viewbox x:Name="PART_Viewbox" Stretch="None"
                   RenderTransformOrigin
="0.5,0.5">
            
<Viewbox.LayoutTransform>
              
<ScaleTransform ScaleX="{Binding Value, ElementName=slider}"
                              ScaleY
="{Binding Value, ElementName=slider}"/>
            
</Viewbox.LayoutTransform>
            
<ContentPresenter Content="{TemplateBinding Content}"/>
          
</Viewbox>
        
</Grid>
      
</ScrollViewer>
    
</DockPanel>
  
</ControlTemplate>

  
<Style TargetType="{x:Type local:DesignViewer}">
    
<Setter Property="Template"
            Value
="{StaticResource DesignViewerTemplate}"/>
  
</Style>
</ResourceDictionary>

 

 

其中,使用了ViewboxSlider来控制缩放,使用了Thumb控件控制拖拽功能,当然还使用了一个ScrollViewer来显示滚动条。

 

完整的程序可以在这里下载

posted on 2009-12-26 22:46  南柯之石  阅读(4692)  评论(2编辑  收藏  举报

导航