1.封装基类ComponentBase.cs 继承自UserControl,定义组件中使用的属性和命令
public class ComponentBase : UserControl { private bool _isSelected; public bool IsSelected { get { return _isSelected; } set { _isSelected = value; if (value) { var parent = VisualTreeHelper.GetParent(this) as Grid; if (parent != null) { foreach (var item in parent.Children) { if (item is ComponentBase) (item as ComponentBase).IsSelected = false; } } } VisualStateManager.GoToState(this, value ? "Selected" : "Unselected", false); } } public bool IsRunning { get { return (bool)GetValue(IsRunningProperty); } set { SetValue(IsRunningProperty, value); } } public static readonly DependencyProperty IsRunningProperty = DependencyProperty.Register("IsRunning", typeof(bool), typeof(ComponentBase), new PropertyMetadata(default(bool), new PropertyChangedCallback(OnRunningChanged))); private static void OnRunningChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { VisualStateManager.GoToState(d as ComponentBase, (bool)e.NewValue ? "RunState" : "Stop", false); } public bool IsFaultState { get { return (bool)GetValue(IsFaultStateProperty); } set { SetValue(IsFaultStateProperty, value); } } public static readonly DependencyProperty IsFaultStateProperty = DependencyProperty.Register("IsFaultState", typeof(bool), typeof(ComponentBase), new PropertyMetadata(default(bool), new PropertyChangedCallback(OnFaultStateChanged))); private static void OnFaultStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { VisualStateManager.GoToState(d as ComponentBase, (bool)e.NewValue ? "FaultState" : "NormalState", false); } public ICommand Command { get { return (ICommand)GetValue(CommandProperty); } set { SetValue(CommandProperty, value); } } public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(ComponentBase), new PropertyMetadata(default(ICommand))); public object CommandParameter { get { return (object)GetValue(CommandParameterProperty); } set { SetValue(CommandParameterProperty, value); } } public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(ComponentBase), new PropertyMetadata(default(object))); public ComponentBase() { this.PreviewMouseLeftButtonDown += ComponentBase_PreviewMouseLeftButtonDown; } private void ComponentBase_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { this.IsSelected = !this.IsSelected; this.Command?.Execute(this.CommandParameter); e.Handled = true; } }
2.编写设计冷却塔组件CoolingTower.xaml,使用<local:ComponentBase>节点包裹,绑定基础组件类中的上下文
<local:ComponentBase x:Class="Wpf.Industrial.Controls.CoolingTower" 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:Wpf.Industrial.Controls" mc:Ignorable="d" Cursor="Hand" d:DesignHeight="450" d:DesignWidth="800"> <Border BorderThickness="1" x:Name="frame"> <VisualStateManager.VisualStateGroups> <VisualStateGroup Name="SelectStateGroup"> <VisualState Name="Selected"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush)" Storyboard.TargetName="frame"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <SolidColorBrush Color="Orange"/> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState Name="Unselected"/> </VisualStateGroup> <VisualStateGroup Name="RunStateGroup"> <VisualState Name="RunState"> <Storyboard> <DoubleAnimation Duration="00:0:0.5" From="0" To="-360" RepeatBehavior="Forever" Storyboard.TargetProperty="(RotateTransform.Angle)" Storyboard.TargetName="rt"/> <ColorAnimationUsingKeyFrames Storyboard.TargetName="gsGreen" Storyboard.TargetProperty="Color"> <DiscreteColorKeyFrame Value="Green" KeyTime="0"/> </ColorAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState Name="Stop"/> </VisualStateGroup> <VisualStateGroup x:Name="FaultStateGroup"> <VisualState Name="FaultState"> <Storyboard> <ColorAnimationUsingKeyFrames RepeatBehavior="Forever" Storyboard.TargetName="gsRed1" Storyboard.TargetProperty="Color"> <DiscreteColorKeyFrame Value="Red" KeyTime="0:0:0.5"/> <DiscreteColorKeyFrame Value="Gray" KeyTime="0:0:1"/> </ColorAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState Name="NormalState"/> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Viewbox VerticalAlignment="Center" HorizontalAlignment="Center"> <Canvas Width="205" Height="245" Margin="5"> <Polygon Points="0,65 40,10 205,10 180,65" Fill="#EEE"/> <Path Data="M0 0A60 15 0 0 0 120 0L120 25A60 15 0 0 1 0 25" Canvas.Left="45" HorizontalAlignment="Center" Margin="0,15,0,0"> <Path.Fill> <LinearGradientBrush EndPoint="1,0" StartPoint="0,0"> <GradientStop Color="#FFD6D6D6" Offset="0"/> <GradientStop Color="White" Offset="0.519"/> <GradientStop Color="#FFD6D6D6" Offset="1"/> </LinearGradientBrush> </Path.Fill> </Path> <Ellipse Width="120" Height="30" Fill="#CCC" VerticalAlignment="Top" Canvas.Left="45"/> <Border VerticalAlignment="Top" Canvas.Left="50" Canvas.Top="-40"> <Viewbox Width="110" Height="110" RenderTransformOrigin="0.5,0.5"> <Viewbox.RenderTransform> <TransformGroup> <RotateTransform Angle="0" x:Name="rt"/> <ScaleTransform ScaleY="0.25"/> </TransformGroup> </Viewbox.RenderTransform> <Path Data="M605.61792 481.6c110.464-39.808 281.6-67.584 376.192 33.536 92.672 98.944 31.168 350.016-167.232 395.904-186.496 43.136-27.456-356.736-246.912-313.6a108.224 108.224 0 0 1-22.4 15.104c38.4 110.592 62.656 276.416-36.224 369.024s-350.08 31.168-395.968-167.232c-41.344-178.816 325.248-39.424 317.44-220.992a107.648 107.648 0 0 1-30.592-44.8c-110.592 36.288-268.032 55.616-357.504-39.68C-50.44608 409.984 11.18592 159.04 210.03392 113.152c179.2-41.28 40.128 323.648 220.608 317.184a107.584 107.584 0 0 1 46.848-23.04c-37.376-110.784-59.648-273.472 37.824-364.8C614.44992-50.496 865.20192 11.136 911.08992 209.984c43.456 188.48-363.328 24.832-312.256 252.928a106.304 106.304 0 0 1 6.784 18.688z" Fill="#EEE"> </Path> </Viewbox> </Border> <Grid Grid.Row="1" Width="180" Height="180" Background="LightGray" Canvas.Top="65"> <Border VerticalAlignment="Top" Height="140" BorderThickness="10"> <Border.Background> <DrawingBrush TileMode="Tile" ViewportUnits="Absolute" Viewport="1,0,25,1"> <DrawingBrush.Drawing> <GeometryDrawing> <GeometryDrawing.Pen> <Pen Brush="#EEE"/> </GeometryDrawing.Pen> <GeometryDrawing.Geometry> <PathGeometry> <PathFigure> <LineSegment Point="10,0"/> <LineSegment Point="10,10"/> </PathFigure> </PathGeometry> </GeometryDrawing.Geometry> </GeometryDrawing> </DrawingBrush.Drawing> </DrawingBrush> </Border.Background> </Border> <Grid VerticalAlignment="Bottom" Height="40" Margin="5"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Border Background="#FFAAAAAA" Margin="2"/> <Border Background="#FFAAAAAA" Margin="2" Grid.Column="1"/> </Grid> </Grid> <Grid Grid.Row="1" Width="180" Height="180" Background="LightGray" Canvas.Top="65" Canvas.Left="180"> <Grid.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="0.139"/> <SkewTransform AngleY="-65.5"/> </TransformGroup> </Grid.RenderTransform> <Border VerticalAlignment="Top" Height="140" BorderThickness="10"> <Border.Background> <DrawingBrush TileMode="Tile" ViewportUnits="Absolute" Viewport="1,0,25,1"> <DrawingBrush.Drawing> <GeometryDrawing> <GeometryDrawing.Pen> <Pen Brush="#EEE"/> </GeometryDrawing.Pen> <GeometryDrawing.Geometry> <PathGeometry> <PathFigure> <LineSegment Point="10,0"/> <LineSegment Point="10,10"/> </PathFigure> </PathGeometry> </GeometryDrawing.Geometry> </GeometryDrawing> </DrawingBrush.Drawing> </DrawingBrush> </Border.Background> </Border> <Grid VerticalAlignment="Bottom" Height="40" Margin="5"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Border Background="#FFAAAAAA" Margin="2"/> <Border Background="#FFAAAAAA" Margin="2" Grid.Column="1"/> </Grid> </Grid> <Border Width="18" Height="18" CornerRadius="10" Canvas.Left="150" Canvas.Top="80"> <Border.Background> <RadialGradientBrush> <GradientStop Color="Gray" Offset="0.5" x:Name="gsGreen"/> <GradientStop Color="White"/> </RadialGradientBrush> </Border.Background> </Border> <Border Width="18" Height="18" CornerRadius="10" Canvas.Left="150" Canvas.Top="105"> <Border.Background> <RadialGradientBrush> <GradientStop Color="Gray" Offset="0.6" x:Name="gsRed1"/> <GradientStop Color="White"/> </RadialGradientBrush> </Border.Background> </Border> </Canvas> </Viewbox> </Border> </local:ComponentBase>
后台代码继承ComponentBase基类
/// <summary> /// CoolingTower.xaml 的交互逻辑 /// </summary> public partial class CoolingTower : ComponentBase { public CoolingTower() { InitializeComponent(); } }
3.使用该组件
<!--冷却塔--> <control:CoolingTower Width="90" Height="110" Command="{Binding ComponentCommand}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="125,0,0,95"/>
标签:冷却塔,DependencyProperty,ComponentBase,value,bool,typeof,组件,WPF,public From: https://www.cnblogs.com/jiangyuhu/p/18673261