WPF旋转板栈设计一例

效果图

项目中需要做一个机台的平面视图,点击其中一个料盒时,弹出该料盒的料管列表,用WPF示例做了一下,效果如下:

WPF旋转板栈设计一例

用户控件XAML

WPF旋转板栈设计一例

 1 <UserControl x:Class="WpfApp1.Views.BoardStackControl"  2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"   6              xmlns:b="http://schemas.microsoft.com/xaml/behaviors"  7              xmlns:local="clr-namespace:WpfApp1.Views"  8              xmlns:wpfapp1="clr-namespace:WpfApp1"  9              d:DataContext="{d:DesignInstance Type=wpfapp1:MainViewModel}" 10              Width="224" Height="300" 11              mc:Ignorable="d"  12              d:DesignHeight="300" d:DesignWidth="250"> 13     <UserControl.DataContext> 14         <wpfapp1:MainViewModel /> 15     </UserControl.DataContext> 16     <Grid> 17         <!--<ItemsControl ItemsSource="{Binding NestGroups}"> 18             <ItemsControl.ItemsPanel> 19                 <ItemsPanelTemplate> 20                     <StackPanel Orientation="Horizontal"></StackPanel> 21                 </ItemsPanelTemplate> 22             </ItemsControl.ItemsPanel> 23             <ItemsControl.ItemTemplate> 24                 <DataTemplate>--> 25         <Border Margin="1"> 26             <Grid Width="220" Height="220"> 27                 <Ellipse Stroke="#dcdfe3" StrokeThickness="3"  Width="220" Height="220"/> 28                 <Ellipse Stroke="#dcdfe3" StrokeThickness="3"  Width="80" Height="80" HorizontalAlignment="Center" VerticalAlignment="Center"/> 29                 <ItemsControl ItemsSource="{Binding LeftTubes3}"> 30                     <ItemsControl.ItemsPanel> 31                         <ItemsPanelTemplate> 32                             <Canvas/> 33                         </ItemsPanelTemplate> 34                     </ItemsControl.ItemsPanel> 35                     <ItemsControl.ItemContainerStyle> 36                         <Style TargetType="ContentPresenter"> 37                             <Setter Property="Canvas.Left"  Value="{Binding X, Mode=OneWay}"/> 38                             <Setter Property="Canvas.Top"  Value="{Binding Y, Mode=OneWay}"/> 39                             <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/> 40                             <Setter Property="RenderTransform"> 41                                 <Setter.Value> 42                                     <RotateTransform Angle="{Binding Angle}"/> 43                                 </Setter.Value> 44                             </Setter> 45                         </Style> 46                     </ItemsControl.ItemContainerStyle> 47                     <ItemsControl.ItemTemplate> 48                         <DataTemplate> 49                             <Grid> 50                                 <Border Width="35" Height="50" Tag="{Binding .}" x:Name="animatedBorder" MouseLeftButtonDown="Border_MouseLeftButtonDown"  51                         CornerRadius="3"  Background="#FFE6E6E6" BorderBrush="Gray" BorderThickness="1"> 52                                     <ItemsControl ItemsSource="{Binding Tubes}" Margin="2" IsHitTestVisible="False"> 53                                         <ItemsControl.ItemsPanel> 54                                             <ItemsPanelTemplate> 55                                                 <UniformGrid Columns="{Binding Rows}" Rows="{Binding Cols}" IsHitTestVisible="False"/> 56                                             </ItemsPanelTemplate> 57                                         </ItemsControl.ItemsPanel> 58                                         <ItemsControl.ItemTemplate> 59                                             <DataTemplate> 60                                                 <Ellipse Width="{Binding Width}" Height="{Binding Height}" Fill="#FF4F81BD"  Margin="{Binding Margin}" Stroke="Black" StrokeThickness="0.5" IsHitTestVisible="False"/> 61                                             </DataTemplate> 62                                         </ItemsControl.ItemTemplate> 63                                     </ItemsControl> 64                                     <Border.Triggers> 65                                         <EventTrigger RoutedEvent="MouseLeftButtonUp"> 66                                             <BeginStoryboard> 67                                                 <Storyboard> 68                                                     <DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0.5" Duration="0:0:0.1" AutoReverse="True"/> 69                                                 </Storyboard> 70                                             </BeginStoryboard> 71                                         </EventTrigger> 72                                     </Border.Triggers> 73                                 </Border> 74                                 <Border Width="20" Height="20" CornerRadius="10"  Background="#FF4F81BD" BorderBrush="White" BorderThickness="1" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,-10,0,0"> 75                                     <TextBlock Text="{Binding Index}"   Foreground="White" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center"/> 76                                 </Border> 77                             </Grid> 78                         </DataTemplate> 79                     </ItemsControl.ItemTemplate> 80                 </ItemsControl> 81             </Grid> 82         </Border> 83         <!--</DataTemplate> 84             </ItemsControl.ItemTemplate> 85         </ItemsControl>--> 86  87     </Grid> 88 </UserControl> 89  90     

View Code

用户控件XMAL.CS

WPF旋转板栈设计一例

 1 using CommunityToolkit.Mvvm.Messaging;  2 using Microsoft.Extensions.Logging;  3 using System.Collections.ObjectModel;  4 using System.Diagnostics;  5 using System.Windows;  6 using System.Windows.Controls;  7 using System.Windows.Input;  8 using System.Windows.Media;  9 using WpfApp1.Entities; 10  11 namespace WpfApp1.Views; 12  13 public partial class BoardStackControl : UserControl 14 { 15     public BoardStackControl() 16     { 17         InitializeComponent(); 18  19     } 20  21     public static readonly RoutedEvent BorderClickedEvent = 22         EventManager.RegisterRoutedEvent( 23             "BorderClicked", 24             RoutingStrategy.Bubble, 25             typeof(RoutedEventHandler), 26             typeof(BoardStackControl) 27         ); 28  29     public event RoutedEventHandler BorderClicked 30     { 31         add => AddHandler(BorderClickedEvent, value); 32         remove => RemoveHandler(BorderClickedEvent, value); 33     } 34  35     private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 36     { 37         if (sender is Border border && border.DataContext is BoxPosition boxPosition) 38         { 39             // 触发路由事件,并携带索引 40             var args = new RoutedEventArgs(BorderClickedEvent, boxPosition.Index); 41             RaiseEvent(args); 42             e.Handled = true; 43         } 44     } 45  46 }

View Code

主窗口XAML

WPF旋转板栈设计一例

 1 <Window x:Class="WpfApp1.MainWindow"  2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  6         xmlns:local="clr-namespace:WpfApp1"  7         xmlns:view="clr-namespace:WpfApp1.Views"  8         mc:Ignorable="d"  9         Title="MainWindow" Height="450" Width="800"> 10     <Window.DataContext> 11         <local:MainViewModel /> 12     </Window.DataContext> 13     <Grid> 14         <Border BorderBrush="Gray" BorderThickness="1"> 15             <Grid> 16                 <Grid.RowDefinitions> 17                     <RowDefinition Height="100"/> 18                     <RowDefinition Height="300"/> 19                 </Grid.RowDefinitions> 20                 <Grid.ColumnDefinitions> 21                     <ColumnDefinition Width="*"></ColumnDefinition> 22                     <ColumnDefinition Width="*"></ColumnDefinition> 23                     <ColumnDefinition Width="*"></ColumnDefinition> 24                 </Grid.ColumnDefinitions> 25  26                 <Border Grid.ColumnSpan="3" Grid.Row="0"  BorderBrush="LightGray" BorderThickness="0,0,0,1"> 27                     <Grid> 28                         <Rectangle Fill="#FFD3D3D3" Height="60" VerticalAlignment="Center"/> 29  30                         <Path Data="M117 91q-6-7 1-12l2-26q-3-1-2-7L85 34q-3 4-8 1L54 48q0 4-5 5L48 54 38 61l-1-1 10-7-3-3-10 6-1-1 10-6 1-1L44 47q1-4 5-4L75 28c2-4 6-5 10-2l40 15q9 0 6 9l2 29q7 5 0 13l14 8v7H101v-7Z"  31                           Fill="#FF4F81BD" Stroke="Black" StrokeThickness="1" 32                           HorizontalAlignment="Center" VerticalAlignment="Center" 33                           Margin="-20,0,0,0" /> 34                     </Grid> 35                 </Border> 36  37                 <view:BoardStackControl Grid.Row="1" Grid.Column="0" BorderClicked="Rack1Control_BorderClicked" /> 38                 <view:BoardStackControl Grid.Row="1" Grid.Column="1" BorderClicked="Rack2Control_BorderClicked" /> 39                 <view:BoardStackControl Grid.Row="1" Grid.Column="2" BorderClicked="Rack3Control_BorderClicked" /> 40             </Grid> 41         </Border> 42     </Grid> 43 </Window>

View Code

主窗口XAML.CS

WPF旋转板栈设计一例

 1 using System.Diagnostics;  2 using System.Text;  3 using System.Windows;  4 using System.Windows.Controls;  5 using System.Windows.Data;  6 using System.Windows.Documents;  7 using System.Windows.Input;  8 using System.Windows.Media;  9 using System.Windows.Media.Imaging; 10 using System.Windows.Navigation; 11 using System.Windows.Shapes; 12 using WpfApp1.Entities; 13 using WpfApp1.Views; 14  15 namespace WpfApp1 16 { 17     /// <summary> 18     /// Interaction logic for MainWindow.xaml 19     /// </summary> 20     public partial class MainWindow : Window 21     { 22         public MainWindow() 23         { 24             InitializeComponent(); 25         } 26  27         private void Rack1Control_BorderClicked(object sender, RoutedEventArgs e) 28         { 29             if (e.OriginalSource is int index) 30             { 31                 MessageBox.Show($"点击了第 1 个板栈的第 {index} 个 Border"); 32                 ExecuteMainWindowMethod(index); 33             } 34         } 35         private void Rack2Control_BorderClicked(object sender, RoutedEventArgs e) 36         { 37             if (e.OriginalSource is int index) 38             { 39                 MessageBox.Show($"点击了第 2 个板栈的第 {index} 个 Border"); 40                 ExecuteMainWindowMethod(index); 41             } 42         } 43         private void Rack3Control_BorderClicked(object sender, RoutedEventArgs e) 44         { 45             if (e.OriginalSource is int index) 46             { 47                 MessageBox.Show($"点击了第 3 个板栈的第 {index} 个 Border"); 48                 ExecuteMainWindowMethod(index); 49             } 50         } 51  52         private void ExecuteMainWindowMethod(int index) 53         { 54             //// 这里编写 MainWindow 的具体逻辑 55             //// 例如更新 UI 或处理业务逻辑 56             //var vm = (MainViewModel)this.DataContext; 57             //vm.RackClickedCommand.Execute($"2_{deviceCode}_{rackIndex}"); 58         } 59     } 60 }

View Code

主窗口ViewModel

WPF旋转板栈设计一例

  1 using CommunityToolkit.Mvvm.ComponentModel;   2 using CommunityToolkit.Mvvm.Input;   3 using CommunityToolkit.Mvvm.Messaging;   4 using System;   5 using System.Collections.Generic;   6 using System.ComponentModel;   7 using System.Diagnostics;   8 using System.Runtime.CompilerServices;   9 using System.Windows.Input;  10 using WpfApp1.Entities;  11 using WpfApp1.Views;  12   13 namespace WpfApp1  14 {  15     public partial class MainViewModel  16     {  17   18         public MainViewModel()  19         {  20   21             LeftTubes3 = CreateCircularTubes(12, 18, 110, 50);  22   23             //IsActive = true;  24         }  25   26         #region 左侧板栈UI  27   28         public List<BoxPosition> LeftTubes3 { get; set; } = [];  29   30         private static List<BoxPosition> CreateCircularTubes(int count, int tubs, double outerRadius, double innerRadius)  31         {  32             var positions = new List<BoxPosition>();  33             double centerX = outerRadius;  34             double centerY = outerRadius;  35   36             for (int i = 0; i < count; i++)  37             {  38                 // 计算角度 (360度均匀分布)  39                 double angleDeg = 360.0 * i / count;  40                 double angleRad = angleDeg * Math.PI / 180.0;  41   42                 // 计算位置 (在内外半径之间)  43                 double radius = (outerRadius + innerRadius) / 2;  44                 double x = centerX + radius * Math.Cos(angleRad) - 17; // 25是料盒宽度的一半  45                 double y = centerY + radius * Math.Sin(angleRad) - 25; // 35是料盒高度的一半  46   47                 // 行数和列数  48                 var rows = 2;  49                 var cols = 3;  50                 var margin = 2;  51                 var width = 10;  52                 var height = 10;  53                 switch (tubs)  54                 {  55                     case 3:  56                         rows = 1;  57                         cols = 3;  58                         margin = 2;  59                         width = 10;  60                         height = 10;  61                         break;  62                     //case 6:  63                     //    rows = 2;  64                     //    cols = 3;  65                     //    break;  66                     case 12:  67                         rows = 3;  68                         cols = 4;  69                         margin = 1;  70                         width = 5;  71                         height = 5;  72                         break;  73                     case 18:  74                         rows = 3;  75                         cols = 6;  76                         margin = 1;  77                         width = 4;  78                         height = 4;  79                         break;  80                     case 96:  81                         rows = 8;  82                         cols = 12;  83                         margin = 0;  84                         width = 1;  85                         height = 1;  86                         break;  87                 }  88   89                 // 创建6个料管  90                 var tubes = new List<Tube>();  91                 for (int j = 0; j < tubs; j++)  92                 {  93                     tubes.Add(new Tube  94                     {  95                         Margin = margin,  96                         Width = width,  97                         Height = height,  98                     });  99                 } 100  101                 positions.Add(new BoxPosition 102                 { 103                     Index = i + 1, 104                     X = x, 105                     Y = y, 106                     Rows = rows, 107                     Cols = cols, 108                     Angle = angleDeg + 90, // 旋转角度等于位置角度 109                     Tubes = tubes 110                 }); 111             } 112  113             return positions; 114         } 115  116  117         #endregion 118  119     } 120 }

View Code

Entities

WPF旋转板栈设计一例

 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Text;  5 using System.Threading.Tasks;  6   7 namespace WpfApp1.Entities  8 {  9     public class NestGroup 10     { 11         public List<BoxPosition> Nests { get; set; } = []; 12     } 13     public class BoxPosition 14     { 15         public int Index { get; set; } 16         public double X { get; set; } 17         public double Y { get; set; } 18         public double Angle { get; set; } 19         public int Rows { get; set; } = 2; 20         public int Cols { get; set; } = 3; 21         public List<Tube> Tubes { get; set; } = []; 22     } 23  24     public class Tube 25     { 26         public int Margin { get; set; } = 2; 27         public int Width { get; set; } = 10; 28         public int Height { get; set; } = 10; 29     } 30 }

View Code

 

发表评论

评论已关闭。

相关文章