效果图
项目中需要做一个机台的平面视图,点击其中一个料盒时,弹出该料盒的料管列表,用WPF示例做了一下,效果如下:
用户控件XAML
- 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
- 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
- 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
- 86
- 87 </Grid>
- 88 </UserControl>
- 89
- 90
复制代码 View Code用户控件XMAL.CS
- 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
- 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
- 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
- 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 CodeEntities
- 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
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |