激光切割道生成并按要求排序

image
我在做激光切割的时候,客户要求上位机按照切割轨迹生成示意图,并且要标注方向和多段线的指定顺序,如图:
1、首先我们知道多段线我们可以封装到ItemsControl,至于画线段,可以使用Line控件或者Border当作类似元素处理。
接着我们需要填充DataTemplate
代码如下:

  <ItemsControl  AlternationCount="1000"
      HorizontalAlignment="Center"
      VerticalAlignment="Bottom"
      ItemTemplate="{StaticResource HorizontalDashTemplate}"
      ItemsSource="{Binding BottomDashCount, Converter={StaticResource CountConverter}}"
      Tag="Bottom">
      <ItemsControl.ItemsPanel>
          <ItemsPanelTemplate>
              <StackPanel Orientation="Horizontal" />
          </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>
  </ItemsControl>
   <DataTemplate x:Key="VerticalDashTemplate">
     <Grid>
         <Border
             Width="3"
             Height="60"
             Margin="10,10"
             BorderBrush="Green"
             BorderThickness="2" />
     </Grid>
 </DataTemplate>

2、因为我们有4边,所以单独处理
接着我们需要将指定的边转换为Border

  public class CountToEmptyListConverter : IValueConverter
  {
      public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
      {
          if (value is int count && count > 0)
              return new object[count];
          return Array.Empty<object>();
      }

      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
      {
          throw new NotImplementedException();
      }
  }

所以当4条边转换完成后,我们需要对指定的多段线进行排序,
客户现在需要下方为X1切割道,上方为X2切割道,左侧为Y1切割道,右侧为Y2切割道,并且激光切割先切X再切Y
所以,我们需要加上一个TextBlock写入数字,

<DataTemplate x:Key="VerticalDashTemplate">
    <Grid>
        <Border
            Width="3"
            Height="60"
            Margin="10,10"
            BorderBrush="Green"
            BorderThickness="2" />
        <TextBlock Text="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</DataTemplate>

上面我写死了所有的多段线序号Id为1,怎么进行排序处理呢
我们需要用到AlternationCount
3、一、AlternationCount="1000" 的作用原理

  1. 什么是AlternationIndex?
    这是WPF为ItemsControl中的每个项提供的附加属性,用于实现 交替项样式。例如每隔5项换颜色。

  2. 为什么需要设置AlternationCount?
    获取索引的前提:只有设置了AlternationCount(即使设置为非常大的值),才能激活AlternationIndex的计数功能

索引生成规则:AlternationIndex从0开始,每项递增1,直到达到AlternationCount值后重置
所以我们可以完成多转一的数据转换器

 public class DashNumberConverter : IMultiValueConverter
 {
     public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
     {
         if (values == null || values.Length < 6 || values.Any(v => v == DependencyProperty.UnsetValue))
             return "0";

         // 解析所有参数
         int index = (int)values[0];
         string edgeType = values[1] as string;
         int bottomCount = (int)values[2];
         int topCount = (int)values[3];
         int leftCount = (int)values[4];
         int rightCount = (int)values[5];

         // 处理垂直方向索引倒序
         if (edgeType == "Left" || edgeType == "Right")
         {
             var totalItems = edgeType == "Left" ? leftCount : rightCount;
             index = totalItems - index - 1; // 反转索引
         }

         switch (edgeType)
         {
             case "Bottom":
                 return (index + 1).ToString();

             case "Top":
                 return (bottomCount + index + 1).ToString();

             case "Left":
                 return (bottomCount + topCount + index + 1).ToString();

             case "Right":
                 return (bottomCount + topCount + leftCount + index + 1).ToString();

             default:
                 return "0";
         }
     }

     public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
     {
         throw new NotImplementedException();
     }
 }

上面的代码我们将定义一下参数
image
我们的数据模板将变为

 <DataTemplate x:Key="VerticalDashTemplate">
     <Grid>
         <Border
             Width="3"
             Height="60"
             Margin="10,10"
             BorderBrush="Green"
             BorderThickness="2" />
         <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
             <TextBlock.Text>
                 <MultiBinding Converter="{StaticResource DashNumberConverter}">
                     <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource AncestorType={x:Type ContentPresenter}}" />
                     <Binding Path="Tag" RelativeSource="{RelativeSource AncestorType={x:Type ItemsControl}}" />
                     <Binding Path="DataContext.BottomDashCount" RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}" />
                     <Binding Path="DataContext.TopDashCount" RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}" />
                     <Binding Path="DataContext.LeftDashCount"
      RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}" />
                     <Binding Path="DataContext.RightDashCount"
      RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}" />
                 </MultiBinding>
             </TextBlock.Text>
         </TextBlock>
     </Grid>
 </DataTemplate>

完整的代码如下:

  <UserControl.Resources>

      <!--  数量到空对象集合的转换器  -->
      <local:CountToEmptyListConverter x:Key="CountConverter" />
      <local:DashNumberConverter x:Key="DashNumberConverter" />
      <!--  虚线模板  -->
      <DataTemplate x:Key="HorizontalDashTemplate">
          <Grid>
              <Border
                  Width="60"
                  Height="3"
                  Margin="10,0"
                  BorderBrush="Green"
                  BorderThickness="2" />
              <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
                  <TextBlock.Text>
                      <MultiBinding Converter="{StaticResource DashNumberConverter}">
                          <!--  当前项的索引  -->
                          <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource AncestorType={x:Type ContentPresenter}}" />
                          <!--  边类型(通过ItemsControl的Tag获取)  -->
                          <Binding Path="Tag" RelativeSource="{RelativeSource AncestorType={x:Type ItemsControl}}" />
                          <!--  BottomDashCount  -->
                          <Binding Path="DataContext.BottomDashCount" RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}" />
                          <!--  TopDashCount  -->
                          <Binding Path="DataContext.TopDashCount" RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}" />
                          <!-- 新增两个绑定 -->
                          <Binding Path="DataContext.LeftDashCount"
           RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}" />
                          <Binding Path="DataContext.RightDashCount"
           RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}" />
                      </MultiBinding>
                  </TextBlock.Text>
              </TextBlock>
          </Grid>
      </DataTemplate>

      <DataTemplate x:Key="VerticalDashTemplate">
          <Grid>
              <Border
                  Width="3"
                  Height="60"
                  Margin="10,10"
                  BorderBrush="Green"
                  BorderThickness="2" />
              <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
                  <TextBlock.Text>
                      <MultiBinding Converter="{StaticResource DashNumberConverter}">
                          <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource AncestorType={x:Type ContentPresenter}}" />
                          <Binding Path="Tag" RelativeSource="{RelativeSource AncestorType={x:Type ItemsControl}}" />
                          <Binding Path="DataContext.BottomDashCount" RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}" />
                          <Binding Path="DataContext.TopDashCount" RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}" />
                          <!-- 新增两个绑定 -->
                          <Binding Path="DataContext.LeftDashCount"
           RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}" />
                          <Binding Path="DataContext.RightDashCount"
           RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}" />
                      </MultiBinding>
                  </TextBlock.Text>
              </TextBlock>
          </Grid>
      </DataTemplate>
  </UserControl.Resources>

  <Grid HorizontalAlignment="Center" VerticalAlignment="Center">

      <!--  顶部虚线  -->
      <ItemsControl  AlternationCount="1000"
          HorizontalAlignment="Center"
          VerticalAlignment="Top"
          ItemTemplate="{StaticResource HorizontalDashTemplate}"
          ItemsSource="{Binding TopDashCount, Converter={StaticResource CountConverter}}"
          Tag="Top">
          <ItemsControl.ItemsPanel>
              <ItemsPanelTemplate>
                  <StackPanel Orientation="Horizontal" />
              </ItemsPanelTemplate>
          </ItemsControl.ItemsPanel>
      </ItemsControl>

      <!--  底部虚线  -->

      <ItemsControl  AlternationCount="1000"
          HorizontalAlignment="Center"
          VerticalAlignment="Bottom"
          ItemTemplate="{StaticResource HorizontalDashTemplate}"
          ItemsSource="{Binding BottomDashCount, Converter={StaticResource CountConverter}}"
          Tag="Bottom">
          <ItemsControl.ItemsPanel>
              <ItemsPanelTemplate>
                  <StackPanel Orientation="Horizontal" />
              </ItemsPanelTemplate>
          </ItemsControl.ItemsPanel>
      </ItemsControl>

      <!--  左侧虚线  -->

      <ItemsControl  AlternationCount="1000"
          HorizontalAlignment="Left"
          VerticalAlignment="Center"
          ItemTemplate="{StaticResource VerticalDashTemplate}"
          ItemsSource="{Binding LeftDashCount, Converter={StaticResource CountConverter}}"
          Tag="Left">
          <ItemsControl.ItemsPanel>
              <ItemsPanelTemplate>
                  <StackPanel Orientation="Vertical" />
              </ItemsPanelTemplate>
          </ItemsControl.ItemsPanel>
      </ItemsControl>

      <!--  右侧虚线  -->

      <ItemsControl  AlternationCount="1000"
          HorizontalAlignment="Right"
          VerticalAlignment="Center"
          ItemTemplate="{StaticResource VerticalDashTemplate}"
          ItemsSource="{Binding RightDashCount, Converter={StaticResource CountConverter}}"
          Tag="Right">
          <ItemsControl.ItemsPanel>
              <ItemsPanelTemplate>
                  <StackPanel Orientation="Vertical" />
              </ItemsPanelTemplate>
          </ItemsControl.ItemsPanel>
      </ItemsControl>
  </Grid>
posted @ 2025-04-04 20:22  孤沉  阅读(66)  评论(0)    收藏  举报