代码Toolbox.cs如下:

 

代码
     
     
     
     
public class Toolbox : ItemsControl
{
private Size defaultItemSize = new Size( 65 , 65 );
public Size DefaultItemSize
{
get { return this .defaultItemSize; }
set { this .defaultItemSize = value; }
}

protected override DependencyObject GetContainerForItemOverride()
{
return new ToolboxItem();
}

protected override bool IsItemItsOwnContainerOverride( object item)
{
return (item is ToolboxItem);
}
}

Toolbox使用WrapPanel显示ToolboxItem,样式文件Toolbox.xaml如下:

 

 

代码
     
     
     
     
< Style TargetType = " {x:Type s:ToolboxItem} " >
< Setter Property = " Control.Padding "
Value
= " 5 " />
< Setter Property = " ContentControl.HorizontalContentAlignment "
Value
= " Stretch " />
< Setter Property = " ContentControl.VerticalContentAlignment "
Value
= " Stretch " />
< Setter Property = " ToolTip "
Value
= " {Binding ToolTip} " />
< Setter Property = " Template " >
< Setter.Value >
< ControlTemplate TargetType = " {x:Type s:ToolboxItem} " >
< Grid >
< Rectangle Name = " Border "
StrokeThickness
= " 1 "
StrokeDashArray
= " 2 "
Fill
= " Transparent "
SnapsToDevicePixels
= " true " />
< ContentPresenter Content = " {TemplateBinding ContentControl.Content} "
Margin
= " {TemplateBinding Padding} "
SnapsToDevicePixels
= " {TemplateBinding UIElement.SnapsToDevicePixels} " />
Grid >
< ControlTemplate.Triggers >
< Trigger Property = " IsMouseOver "
Value
= " true " >
< Setter TargetName = " Border "
Property
= " Stroke "
Value
= " Gray " />
Trigger >
ControlTemplate.Triggers >
ControlTemplate >
Setter.Value >
Setter >
Style >

< Style TargetType = " {x:Type s:Toolbox} " >
< Setter Property = " SnapsToDevicePixels "
Value
= " true " />
< Setter Property = " Focusable "
Value
= " False " />
< Setter Property = " Template " >
< Setter.Value >
< ControlTemplate >
< Border BorderThickness = " {TemplateBinding Border.BorderThickness} "
Padding
= " {TemplateBinding Control.Padding} "
BorderBrush
= " {TemplateBinding Border.BorderBrush} "
Background
= " {TemplateBinding Panel.Background} "
SnapsToDevicePixels
= " True " >
< ScrollViewer VerticalScrollBarVisibility = " Auto " >
< ItemsPresenter SnapsToDevicePixels = " {TemplateBinding UIElement.SnapsToDevicePixels} " />
ScrollViewer >
Border >
ControlTemplate >
Setter.Value >
Setter >
< Setter Property = " ItemsPanel " >
< Setter.Value >
< ItemsPanelTemplate >
< WrapPanel Margin = " 0,5,0,5 "
ItemHeight
= " {Binding Path=DefaultItemSize.Height, RelativeSource={RelativeSource AncestorType=s:Toolbox}} "
ItemWidth
= " {Binding Path=DefaultItemSize.Width, RelativeSource={RelativeSource AncestorType=s:Toolbox}} " />
ItemsPanelTemplate >
Setter.Value >
Setter >
Style >

 

  • ToolboxItem

ToolboxItem是显示在工具箱中的对象,我们可以通过鼠标点击它进行选择,然后拖拽到DesignerCanvas来生成一个设计对象,示例中是通过XamlWriter.Save保存到DataObject,然后在DesignerCanvas接收这个对象,这部分在进行自己的设计器开发时会进行更改
ToolboxItem的代码如下:

代码
     
     
     
     
public class ToolboxItem : ContentControl
{
private Point ? dragStartPoint = null ;

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

protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
base .OnPreviewMouseDown(e);
this .dragStartPoint = new Point ? (e.GetPosition( this ));
}

protected override void OnMouseMove(MouseEventArgs e)
{
base .OnMouseMove(e);
if (e.LeftButton != MouseButtonState.Pressed)
{
this .dragStartPoint = null ;
}
if ( this .dragStartPoint.HasValue)
{
Point position
= e.GetPosition( this );
if ((SystemParameters.MinimumHorizontalDragDistance <=
Math.Abs((
double )(position.X - this .dragStartPoint.Value.X))) ||
(SystemParameters.MinimumVerticalDragDistance
<=
Math.Abs((
double )(position.Y - this .dragStartPoint.Value.Y))))
{
string xamlString = XamlWriter.Save( this .Content);
DataObject dataObject
= new DataObject( " DESIGNER_ITEM " , xamlString);

if (dataObject != null )
{
DragDrop.DoDragDrop(
this , dataObject, DragDropEffects.Copy);
}
}
e.Handled
= true ;
}
}
}

DesignerItem增加IsSelected属性

DesignerItem增加是否选择属性,代码如下:

代码
     
     
     
     
public class DesignerItem : ContentControl
{
public bool IsSelected
{
get { return ( bool )GetValue(IsSelectedProperty); }
set { SetValue(IsSelectedProperty, value); }
}
public static readonly DependencyProperty IsSelectedProperty =
DependencyProperty.Register(
" IsSelected " , typeof ( bool ),
typeof (DesignerItem),
new FrameworkPropertyMetadata( false ));
...

}

在MouseDown事件时会去设置IsSelected属性:

 

 

代码
     
     
     
     
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
base .OnPreviewMouseDown(e);
DesignerCanvas designer
= VisualTreeHelper.GetParent( this ) as DesignerCanvas;

if (designer != null )
{
if ((Keyboard.Modifiers &
(ModifierKeys.Shift
| ModifierKeys.Control)) != ModifierKeys.None)
{
this .IsSelected = ! this .IsSelected;
}
else
{
if ( ! this .IsSelected)
{
designer.DeselectAll();
this .IsSelected = true ;
}
}
}

e.Handled
= false ;
}

IsSelected属性触发ResizeDecorator是否显示:

代码
     
     
     
     
< Style TargetType = " {x:Type s:DesignerItem} " >
< Setter Property = " MinHeight " Value = " 50 " />
< Setter Property = " MinWidth " Value = " 50 " />
< Setter Property = " SnapsToDevicePixels " Value = " true " />
< Setter Property = " Template " >
< Setter.Value >
< ControlTemplate TargetType = " {x:Type s:DesignerItem} " >
< Grid DataContext = " {Binding RelativeSource={RelativeSource TemplatedParent},
Path = .} " >
< s:MoveThumb
x:Name
= " PART_MoveThumb "
Cursor
= " SizeAll "
Template
= " {StaticResource MoveThumbTemplate} " />
< ContentPresenter
x:Name
= " PART_ContentPresenter "
Content
= " {TemplateBinding ContentControl.Content} "
Margin
= " {TemplateBinding Padding} " />
< s:ResizeDecorator x:Name = " PART_DesignerItemDecorator " />
Grid >
< ControlTemplate.Triggers >
< Trigger Property = " IsSelected " Value = " True " >
< Setter TargetName = " PART_DesignerItemDecorator "
Property
= " ShowDecorator " Value = " True " />
Trigger >
ControlTemplate.Triggers >
ControlTemplate >
Setter.Value >
Setter >
Style >

DesignerItem支持移动选择区域

WPF:从WPF Diagram Designer Part 2学习面板、缩略图、框线选择和工具箱-下_第1张图片   WPF:从WPF Diagram Designer Part 2学习面板、缩略图、框线选择和工具箱-下_第2张图片

DesignerItem默认允许移动的是一个透明的矩形区域,如上图左边这个。我们一般希望点击这个形状内部才允许移动和选择,这时候我们可以通过DesignerItem.MoveThumbTemplate来更改这个支持Move的区域,代码如下:

    
    
    
    
< Path Stroke = " Red " StrokeThickness = " 5 " Stretch = " Fill " IsHitTestVisible = " false "
Data
= " M 9,2 11,7 17,7 12,10 14,15 9,12 4,15 6,10 1,7 7,7 Z " >
< s:DesignerItem. MoveThumbTemplate >
< ControlTemplate >
< Path Data = " M 9,2 11,7 17,7 12,10 14,15 9,12 4,15 6,10 1,7 7,7 Z "
Fill
= " Transparent " Stretch = " Fill " />
ControlTemplate >
s:DesignerItem. MoveThumbTemplate   >
Path >

 

 

 

欢迎转载,转载请注明:转载自周金根 [ http://zhoujg.cnblogs.com/ ]