在《WPF高级编程》中作者介绍StyleSeletor时,使用了ListView控件展现了器功能;这篇文章将使用ItemControl介绍StyleSelector展现它更强大的编辑能力。 首相我们介绍在XAML里面定义如下:
<UserControl x:Class="AGVDisplay.UserControls.DiagramControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:AGVDisplay.UserControls"
xmlns:s="clr-namespace:AGVDisplay.StyleSelectors"
xmlns:ucdp="clr-namespace:UICommon.UserControls.DrawParts;assembly=UICommon"
xmlns:att="clr-namespace:UICommon.AttachedProperties;assembly=UICommon"
xmlns:arrows="clr-namespace:UICommon.UserControls.DrawParts.Arrows;assembly=UICommon"
xmlns:con="clr-namespace:UICommon.Converters;assembly=UICommon"
mc:Ignorable="d"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:hc="https://handyorg.github.io/handycontrol"
d:DesignHeight="450" d:DesignWidth="800">
<Border>
<ItemsControl ItemsSource="{Binding Items}" ClipToBounds="True" ItemContainerStyleSelector="{x:Static s:DesignerItemsControlItemStyleSelector.Instance}">
<ItemsControl.Resources>
<!--地标-->
<Style x:Key="designerItemlandmarkStyle"
TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.ZIndex"
Value="6000" />
<Setter Property="Canvas.Top"
Value="{Binding Top}" />
<Setter Property="Canvas.Left"
Value="{Binding Left}" />
<Setter Property="Width"
Value="{Binding ItemWidth}"/>
<Setter Property="Height"
Value="{Binding ItemHeight}"/>
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform CenterX="0.5" CenterY="0.5" ScaleY="{Binding Parent.Zoom}" ScaleX="{Binding Parent.Zoom}"></ScaleTransform>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border x:Name="selectedborder" BorderThickness="2" CornerRadius="20" >
<Border.BorderBrush>
<SolidColorBrush Color="#1F47A6" Opacity="{Binding Opacity}"></SolidColorBrush>
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush Color="#3B6CCF" Opacity="{Binding Opacity}"></SolidColorBrush>
</Border.Background>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap" Text="{Binding LandCode}" Foreground="#C6DC2E" FontSize="12"/>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!--储位-->
<Style x:Key="designerItemstorageStyle"
TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.ZIndex"
Value="4000" />
<Setter Property="Canvas.Top"
Value="{Binding Top}" />
<Setter Property="Canvas.Left"
Value="{Binding Left}" />
<Setter Property="Width"
Value="{Binding ItemWidth}"/>
<Setter Property="Height"
Value="{Binding ItemHeight}"/>
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform CenterX="0.5" CenterY="0.5" ScaleY="{Binding Parent.Zoom}" ScaleX="{Binding Parent.Zoom}"></ScaleTransform>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border x:Name="selectedborder" BorderThickness="3" CornerRadius="20">
<Border.BorderBrush>
<SolidColorBrush Color="#53a6c1" Opacity="0.3 "></SolidColorBrush>
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush Color="{Binding ContentColor}" Opacity="0.2 "></SolidColorBrush>
</Border.Background>
<Grid>
<Grid x:Name="PART_LockDecorator" Margin="3" >
<Path Data="{StaticResource LockGeometry}" Stretch="Fill" Fill="#5f6c82"></Path>
</Grid>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap" Text="{Binding StorageCode}" Foreground="#C6DC2E" FontSize="12"/>
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger Value="True"
Binding="{Binding IsLocked}">
<Setter TargetName="PART_LockDecorator"
Property="Visibility"
Value="Visible" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!--文本-->
<Style x:Key="designerItemtextStyle"
TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.ZIndex"
Value="3000" />
<Setter Property="Canvas.Top"
Value="{Binding Top}" />
<Setter Property="Canvas.Left"
Value="{Binding Left}" />
<Setter Property="att:SelectionProps.EnabledForSelection"
Value="False" />
<Setter Property="att:ItemConnectProps.EnabledForConnection"
Value="False" />
<Setter Property="Width"
Value="{Binding ItemWidth}"/>
<Setter Property="Height"
Value="{Binding ItemHeight}"/>
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform CenterX="0.5" CenterY="0.5" ScaleY="{Binding Parent.Zoom}" ScaleX="{Binding Parent.Zoom}"></ScaleTransform>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border x:Name="selectedborder" BorderThickness="3" CornerRadius="5">
<Border.BorderBrush>
<SolidColorBrush Color="{Binding BordergroundColor}" Opacity="0.5"></SolidColorBrush>
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush Color="{Binding BackgroundColor}" Opacity="{Binding BgOpacity}"></SolidColorBrush>
</Border.Background>
<Grid>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap"
Text="{Binding ContentText}"
FontSize="{Binding FontSize}" >
<TextBlock.Foreground>
<SolidColorBrush Color="{Binding ForegroundColor}"></SolidColorBrush>
</TextBlock.Foreground>
</TextBlock>
</Grid>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!--图片-->
<Style x:Key="designerItemimageStyle"
TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.ZIndex"
Value="3000" />
<Setter Property="Canvas.Top"
Value="{Binding Top}" />
<Setter Property="Canvas.Left"
Value="{Binding Left}" />
<Setter Property="att:SelectionProps.EnabledForSelection"
Value="False" />
<Setter Property="att:ItemConnectProps.EnabledForConnection"
Value="False" />
<Setter Property="Width"
Value="{Binding ItemWidth}"/>
<Setter Property="Height"
Value="{Binding ItemHeight}"/>
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform CenterX="0.5" CenterY="0.5" ScaleY="{Binding Parent.Zoom}" ScaleX="{Binding Parent.Zoom}"></ScaleTransform>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border x:Name="selectedborder" BorderThickness="1" CornerRadius="2">
<Grid >
<Grid.Background>
<ImageBrush ImageSource="{Binding Image}" ></ImageBrush>
</Grid.Background>
</Grid>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!--充电桩-->
<Style x:Key="designerItemchargeStyle"
TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.ZIndex"
Value="3000" />
<Setter Property="Canvas.Top"
Value="{Binding Top}" />
<Setter Property="Canvas.Left"
Value="{Binding Left}" />
<Setter Property="att:SelectionProps.EnabledForSelection"
Value="True" />
<Setter Property="att:ItemConnectProps.EnabledForConnection"
Value="False" />
<Setter Property="Width"
Value="{Binding ItemWidth}"/>
<Setter Property="Height"
Value="{Binding ItemHeight}"/>
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform CenterX="0.5" CenterY="0.5" ScaleY="{Binding Parent.Zoom}" ScaleX="{Binding Parent.Zoom}"></ScaleTransform>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border x:Name="selectedborder" BorderThickness="1" CornerRadius="2">
<Grid >
<Grid.Background>
<ImageBrush ImageSource="{Binding Image}" ></ImageBrush>
</Grid.Background>
<TextBlock Margin="2" Text="{Binding ChargeCode}" Foreground="{StaticResource DarkWarningBrush}" VerticalAlignment="Bottom" HorizontalAlignment="Right" FontSize="20" ></TextBlock>
</Grid>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!--连接线-->
<Style x:Key="connectorItemStyle" TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.ZIndex"
Value="5000" />
<Setter Property="att:SelectionProps.EnabledForSelection"
Value="True" />
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<arrows:AdjustableArrowBezierCurve x:Name="arrows" Stroke="#00C0FF"
IsArrowClosed="True"
ArrowLength="{Binding ArrowLength}"
ArrowEnds="{Binding ConnectorDir,Converter={x:Static con:Direction2ArrowEndsConverter.Instance},UpdateSourceTrigger=PropertyChanged}"
ShowControl="False"
StrokeThickness="{Binding StrokeThickness}"
StartPoint="{Binding StartPoint}"
EndPoint="{Binding EndPoint}" ControlPoint1="{Binding ControlPoint1,Mode=TwoWay}" ControlPoint2="{Binding ControlPoint2,Mode=TwoWay}">
</arrows:AdjustableArrowBezierCurve>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!--机械手-->
<Style x:Key="designerItemmachineStyle"
TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.ZIndex"
Value="3000" />
<Setter Property="Canvas.Top"
Value="{Binding Top}" />
<Setter Property="Canvas.Left"
Value="{Binding Left}" />
<Setter Property="att:SelectionProps.EnabledForSelection"
Value="True" />
<Setter Property="att:ItemConnectProps.EnabledForConnection"
Value="False" />
<Setter Property="Width"
Value="{Binding ItemWidth}"/>
<Setter Property="Height"
Value="{Binding ItemHeight}"/>
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform CenterX="0.5" CenterY="0.5" ScaleY="{Binding Parent.Zoom}" ScaleX="{Binding Parent.Zoom}"></ScaleTransform>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border x:Name="selectedborder" BorderThickness="1" CornerRadius="2">
<Grid >
<Grid.Background>
<ImageBrush ImageSource="{Binding Image}" ></ImageBrush>
</Grid.Background>
</Grid>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!--AGV-->
<Style x:Key="designercarStyle" TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.ZIndex"
Value="8000" />
<Setter Property="Canvas.Top"
Value="{Binding Top}" />
<Setter Property="Canvas.Left"
Value="{Binding Left}" />
<Setter Property="att:SelectionProps.EnabledForSelection"
Value="False" />
<Setter Property="att:ItemConnectProps.EnabledForConnection"
Value="False" />
<Setter Property="Width"
Value="{Binding ItemWidth}"/>
<Setter Property="Height"
Value="{Binding ItemHeight}"/>
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform CenterX="0.5" CenterY="0.5" ScaleY="{Binding Parent.Zoom}" ScaleX="{Binding Parent.Zoom}"></ScaleTransform>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding ShowRouteCommand}" CommandParameter="{Binding AgvID}"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeave">
<i:InvokeCommandAction Command="{Binding HiddenRouteCommand}" CommandParameter="{Binding AgvID}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Viewbox>
<Canvas Width="60" Height="30" Margin="10" ClipToBounds="False" HorizontalAlignment="Center" VerticalAlignment="Center" >
<Border Background="#CDC8C8" CornerRadius="2" Width="60" Height="30" />
<Border Width="4" Height="7" BorderThickness="1" BorderBrush="#9499a1" Background="#384a65" Canvas.Left="4" Canvas.Top="5" />
<Border Height="25" Width="2" CornerRadius="1" Canvas.Top="2" Canvas.Left="-1" Background="Black"/>
<Rectangle Width="3" Height="4" Fill="#00CC00" HorizontalAlignment="Left" Canvas.Left="5" Canvas.Top="15"/>
<Rectangle Width="3" Height="4" Fill="#F40A0A" HorizontalAlignment="Left" Canvas.Left="5" Canvas.Top="20"/>
<Rectangle Width="30" Height="30" Fill="#987306" RadiusX="5" RadiusY="5" Canvas.Left="20" Canvas.Top="0"/>
<Rectangle Width="3" Height="30" Fill="#FFCC00" Canvas.Top="0" Canvas.Left="33"/>
<Rectangle Width="30" Height="3" Fill="#FFCC00" Canvas.Top="14" Canvas.Left="20"/>
</Canvas>
</Viewbox>
<Ellipse Height="60" Width="60" RenderTransformOrigin="0.5 0.5" >
<Ellipse.Fill>
<SolidColorBrush Color="{Binding StateColor}"></SolidColorBrush>
</Ellipse.Fill>
<Ellipse.OpacityMask>
<RadialGradientBrush>
<GradientStop Offset="0" Color="Transparent" />
<GradientStop Offset="1" Color="Black" />
</RadialGradientBrush>
</Ellipse.OpacityMask>
<Ellipse.RenderTransform>
<ScaleTransform />
</Ellipse.RenderTransform>
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)" BeginTime="0" Duration="0:0:1" From="1" To="2" EasingFunction="{StaticResource SineEaseOut}" />
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)" BeginTime="0" Duration="0:0:1" From="1" To="2" EasingFunction="{StaticResource SineEaseOut}" />
<DoubleAnimation Storyboard.TargetProperty="Opacity" BeginTime="0" Duration="0:0:1" From="1" To="0" EasingFunction="{StaticResource SineEaseOut}" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
<Grid Background="Transparent">
<!--<Grid.ToolTip>
<ToolTip></ToolTip>
</Grid.ToolTip>-->
<TextBlock Text="{Binding AgvID}" FontSize="30" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</Grid>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<ucdp:DesignerCanvas Background="Transparent" >
</ucdp:DesignerCanvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Border>
</UserControl>
上面代码中,我们定义一个ItemControl,并且指定ItemPanel为一个Canvas。
接着我们定义自己的StyleSelector:
public class DesignerItemsControlItemStyleSelector : StyleSelector
{
static DesignerItemsControlItemStyleSelector()
{
Instance = new DesignerItemsControlItemStyleSelector();
}
public static DesignerItemsControlItemStyleSelector Instance
{
get;
private set;
}
public override Style SelectStyle(object item, DependencyObject container)
{
ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(container);
if (itemsControl == null)
throw new InvalidOperationException("DesignerItemsControlItemStyleSelector : Could not find ItemsControl");
if (item is DesignerItemLandMarkViewModel)
{
return (Style)itemsControl.FindResource("designerItemlandmarkStyle");
}
if (item is ConnectorViewModel)
{
return (Style)itemsControl.FindResource("connectorItemStyle");
}
if (item is DesignerItemStorageViewModel)
{
return (Style)itemsControl.FindResource("designerItemstorageStyle");
}
if (item is DesignerItemTextViewModel)
{
return (Style)itemsControl.FindResource("designerItemtextStyle");
}
if (item is DesignerItemImageViewModel)
{
return (Style)itemsControl.FindResource("designerItemimageStyle");
}
if (item is DesignerItemChargeViewModel)
{
return (Style)itemsControl.FindResource("designerItemchargeStyle");
}
if (item is DesignerItemMachineViewModel)
{
return (Style)itemsControl.FindResource("designerItemmachineStyle");
}
if (item is DesignerItemCarViewModel)
{
return (Style)itemsControl.FindResource("designercarStyle");
}
return null;
}
}
最终运行效果如下图: