(二十三)运动控制模块和相机模块

1. 添加运动轴控制模块

  1. 用户控件库
  2. 下载reactiveui,fody,wpf,prism.unity.mahapp.metro
  3. 生成事件命令,并添加引用
  4. 模块配置类
  5. 建包views,viewmodels
  6. 创建view和vm并绑定
containerProvider.Resolve<IRegionManager>().RegisterViewWithRegion<AxisView>(RegionNames.AxisRegion);//和filter的区别是那个需要切换导航的不可以直接放到区域里

要实现这个图像功能
image
使用九宫格布局放置按钮
右边用Canvas来放置扇形按钮,用手动拖动布局

2. 增加运动轴的开始移动和停止移动功能

每个按钮都有这两个命令,只是参数不同
左就是x轴反向,右是x轴正向
上y轴正向,下y轴反向
参数新建类
image

  <i:Interaction.Triggers>
      <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
          <i:InvokeCommandAction Command="{Binding StartMoveCommand}">
              <i:InvokeCommandAction.CommandParameter>
                  <models:AxisMoveParameter AxisType="Y" Direction="Forward" />
              </i:InvokeCommandAction.CommandParameter>
          </i:InvokeCommandAction>
      </i:EventTrigger>
      <i:EventTrigger EventName="PreviewMouseLeftButtonUp">
          <i:InvokeCommandAction Command="{Binding EndMoveCommand}">
              <i:InvokeCommandAction.CommandParameter>
                  <models:AxisMoveParameter AxisType="Y" Direction="Forward" />
              </i:InvokeCommandAction.CommandParameter>
          </i:InvokeCommandAction>
      </i:EventTrigger>
  </i:Interaction.Triggers>

对应的方法:

 private void StartMove(AxisMoveParameter arg)
 {
     IsMoving= ControlCard.Move(arg.AxisType, arg.Direction);
 }
 
  private void EndMove(AxisMoveParameter arg)
 {
     if (!IsMoving)
     {
         return;//当前没有处于连续运动的轴,则不执行停止命令
     }
     ControlCard.Stop(arg.AxisType);
     IsMoving = false;
 }
  /// <summary>
 /// 停止所有轴
 /// </summary>
 private void StopMove()
 {
     ControlCard.Stop(null);//传空值,则挨个停止各个轴
 }

3. 控制其它轴并显示运动轴的运动状态

3.1 控制轴

底层方法:
image
移动:
image
image
所以应该在初始化时先回零,在硬件生命周期管理器中
image
这样之后进行轴移动控制就可以实现了
image

3.2 显示运动轴的运动状态

创建一个转换器,IsMoving是一个bool值,转换成文字显示状态

 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
 {
     if (value == null || string.IsNullOrEmpty(value.ToString())) return "未知状态";
     if(bool.TryParse(value.ToString(), out bool result))
     {
         //这个value 的值是False 和 True 的字符串(这个字符串只要组成这两个单词即可,都会转换成功),其他包括数字或者是其它的字符串会返回false。
         return result ?"正在移动":"停止移动";
     }
     else
     {
         return "未知状态";
     }
 }

4. 利用Path开发扇形Button样式

  • Path元素定义了一个图形路径,用于绘制一个自定义的图形(在本例中是一个扇形)。Fill属性通过TemplateBinding绑定到按钮的背景属性,允许路径的填充色随按钮的背景色变化而变化。Stroke="LightBlue"设置了路径的描边颜色为浅蓝色。

  • Path.Data内部定义了具体的图形数据

  • PathGeometry是WPF中一个强大的元素,它允许定义复杂的二维图形。

  • LineSegment 画直线

  • ArcSegment 画弧线 Size属性定义了弧线的大小,通常与弧的二维形状相关;在这个例子中,它使用的是椭圆的半径(宽度300和高度200)SweepDirection="Clockwise"表示弧线的绘制方向是顺时针方向。

  • Panel.ZIndex="99"确保文本显示在扇形之上

 <!--  运动轴扇形按钮样式  -->
 <Style x:Key="AxisButtonStyle" TargetType="Button">
     <Setter Property="Template">
         <!--  通过Setter设置Button的Template属性。这允许你完全重写控件的视觉结构。  -->
         <Setter.Value>
             <ControlTemplate TargetType="Button">
                 <Grid>
                     <Path Fill="{TemplateBinding Background}" Stroke="LightBlue">
                         <Path.Data>
                             <PathGeometry>
                                 <!--  画一个扇形  -->
                                 <PathFigure StartPoint="0,100">
                                     <!--  即扇形的起始位置。在这个例子中,起点是在坐标(0, 100)。  -->
                                     <LineSegment Point="100,0" />
                                     <!--  定义了一条从起始点(StartPoint)到(100, 0)的直线。  -->
                                     <ArcSegment
                                         Point="100,200"
                                         Size="300,200"
                                         SweepDirection="Clockwise" />
                                     <!--  从ArcSegment的终点回到PathFigure的起始点,完成扇形的绘制。  -->
                                     <LineSegment Point="0,100" />
                                 </PathFigure>
                             </PathGeometry>
                         </Path.Data>
                     </Path>
                     <TextBlock
                         HorizontalAlignment="Center"
                         VerticalAlignment="Center"
                         Panel.ZIndex="99"
                         FontSize="50"
                         Foreground="DarkGreen"
                         Text=" ➜" />
                 </Grid>
                 <ControlTemplate.Triggers>
                     <Trigger Property="IsMouseOver" Value="True">
                         <Setter Property="Background" Value="LightGreen" />
                     </Trigger>
                     <Trigger Property="IsPressed" Value="True">
                         <Setter Property="Background" Value="OrangeRed" />
                     </Trigger>
                 </ControlTemplate.Triggers>
             </ControlTemplate>
         </Setter.Value>
     </Setter>
 </Style>

5. 098-读取与写入程序中的缓存数据

5.1 读取

加载FlowViewModel时初始化之前选择的模型,缓存中保存的是算法模型的名字

  private void InitializeCacheFilter()
  {
      CacheManager.Get(CacheKey.Filters, out List<string> filters);
      if (filters != null)
      {
          var all = FilterFactory.CreateFilterModels();//创建所有过滤器
          foreach (var item in filters)
          {
              FlowModel.Filters.Add(all.FirstOrDefault(t=>t.GetType().FullName==item));
          }
      }
  }

5.2 写入

订阅flowModel的观察者,当flowModel中的filter集合发生变化时,给它写入缓存

  private void SaveFilters(Unit unit)
  {
       List<string> filters = new List<string>();
      foreach(var item in FlowModel.Filters)
      {
          filters.Add(item.GetType().FullName);
      }
      CacheManager.Set(CacheKey.Filters, filters);
  }

6. 创建相机预览模块项目

  1. 用户控件库
  2. 下载reactiveui,fody,wpf,prism.unity.mahapp.metro
  3. 生成事件命令,并添加引用
  4. 模块配置类
  5. 建包views,viewmodels
  6. 创建view和vm并绑定
containerProvider.Resolve<IRegionManager>().RegisterViewWithRegion<PreviewView>(RegionNames.CameraRegion);

7. 编写相机预览模块的UI界面

一个groupbox上面是一个菜单,下面显示图像,图像部分可以参考image模块的布局
groupbox的样式
第一行是标题,加个border加背景
第二行是图片区域,设置边框

 <Style x:Key="GroupBoxPreviewCameraStyle" TargetType="GroupBox">
     <Setter Property="Foreground" Value="White"/>
     <Setter Property="Template">
         <Setter.Value>
             <ControlTemplate TargetType="GroupBox">
                 <Grid>
                     <Grid.RowDefinitions>
                         <RowDefinition Height="auto"/>
                         <RowDefinition/>
                     </Grid.RowDefinitions>
                     <Border Grid.Row="0" Background="#3393df" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1">
                         <ContentPresenter Margin="0" ContentSource="Header" RecognizesAccessKey="True"/>
                     </Border>
                     <ContentPresenter Grid.Row="1" Margin="0"/>
                     <Border Grid.Row="1" BorderThickness="1 0 1 1" BorderBrush="{TemplateBinding BorderBrush}"/>
                 </Grid>
             </ControlTemplate>
         </Setter.Value>
     </Setter>
 </Style>
posted @ 2024-02-27 10:45  huihui不会写代码  阅读(104)  评论(0)    收藏  举报