(二十三)运动控制模块和相机模块
1. 添加运动轴控制模块
- 用户控件库
- 下载reactiveui,fody,wpf,prism.unity.mahapp.metro
- 生成事件命令,并添加引用
- 模块配置类
- 建包views,viewmodels
- 创建view和vm并绑定
containerProvider.Resolve<IRegionManager>().RegisterViewWithRegion<AxisView>(RegionNames.AxisRegion);//和filter的区别是那个需要切换导航的不可以直接放到区域里
要实现这个图像功能

使用九宫格布局放置按钮
右边用Canvas来放置扇形按钮,用手动拖动布局
2. 增加运动轴的开始移动和停止移动功能
每个按钮都有这两个命令,只是参数不同
左就是x轴反向,右是x轴正向
上y轴正向,下y轴反向
参数新建类

<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 控制轴
底层方法:

移动:


所以应该在初始化时先回零,在硬件生命周期管理器中

这样之后进行轴移动控制就可以实现了

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. 创建相机预览模块项目
- 用户控件库
- 下载reactiveui,fody,wpf,prism.unity.mahapp.metro
- 生成事件命令,并添加引用
- 模块配置类
- 建包views,viewmodels
- 创建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>


浙公网安备 33010602011771号