我试图在画布上的椭圆之间绘制一组线 . 我分两步完成:
-
以下XAML中的第一部分,其中ItemsControl绑定到'SingleCL',使用嵌套的ItemsControl可视化行,绑定到'Points' .
-
第二部分,绑定相同的集合,可视化椭圆 .
'SingleCL'和'Points'都是ObservableCollection <T>
Point-class有四个属性:VisualHorPos,VisualVerPos,CenterHorPos和CenterVerPos,并实现INotifyPropertyChanged . 属性表示X,Y,其中“Visual”属性被调整为在放置在画布上时表示视图的左上角,因此当使用鼠标移动时,中心位于鼠标指针所在的位置 .
这些点按其各自集合中的Y值进行排序,以便从下到上绘制线条 .
为了避免(隐藏)从0,0到x2绘制的第一行,y2为Point集合中的第一个点,我使用PriorityBinding使其长度为0,因此在实践中隐藏它 .
结果是此图像中显示的红色曲折线
在下面添加点(图像方式) - 首先在集合中 - 仅显示省略号,请参见上图中的蓝点 . 如果我保存数据并从头开始重新加载,则会按预期显示这些行 .
在上面添加点(图像明智) - 在集合中的另一个点之后 - 正确绘制线条,但不更新现有线条以考虑新点 .
我已经验证了这些点是正确排序的,无论是在添加新点还是在沿Y轴移动时 .
也许我对WPF要求太多了,但是我希望它能够在添加新点时根据ObservableCollection <T>'Points'中项目的顺序从点到点绘制线条,而不仅仅是绑定发生的时间 . 此外,在移动点时,我预计线条会刷新,以便始终根据集合中的顺序从下到上绘制 .
我看到它的方式,问题是一旦创建了线,当对象被移动或添加到集合中时,它们不会反弹 . 有没有办法让ItemsControl重新评估基础ObservableCollection <T>中每个Moved / Added / Removed操作的所有项目?
“绘图代码”
<ItemsControl ItemsSource="{Binding SingleCL}">
<ItemsControl.LayoutTransform>
<TransformGroup>
<ScaleTransform ScaleX="{Binding ElementName=imageZoom, Path=Value}" ScaleY="{Binding ElementName=imageZoom, Path=Value}"/>
</TransformGroup>
</ItemsControl.LayoutTransform>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding Points}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line X2="{Binding CenterHorPos, Mode=OneWay}" Y2="{Binding CenterVerPos, Mode=OneWay}" Stroke="{Binding Color}" StrokeThickness="2">
<!-- Bind X1,Y1 to the previous point, or if not available (as for the first data item) to the same as X2,Y2 -->
<Line.X1>
<PriorityBinding>
<Binding Path="CenterHorPos" RelativeSource="{RelativeSource PreviousData}"/>
<!-- This is the value used of the first binding doesn't work -->
<Binding Path="CenterHorPos"/>
</PriorityBinding>
</Line.X1>
<Line.Y1>
<PriorityBinding>
<Binding Path="CenterVerPos" RelativeSource="{RelativeSource PreviousData}"/>
<!-- This is the value used of the first binding doesn't work -->
<Binding Path="CenterVerPos"/>
</PriorityBinding>
</Line.Y1>
</Line>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- Display markers for all centerlines -->
<ItemsControl ItemsSource="{Binding SingleCL}">
<ItemsControl.LayoutTransform>
<TransformGroup>
<ScaleTransform ScaleX="{Binding ElementName=imageZoom, Path=Value}" ScaleY="{Binding ElementName=imageZoom, Path=Value}"/>
</TransformGroup>
</ItemsControl.LayoutTransform>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding Points}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding VisualHorPos}" />
<Setter Property="Canvas.Top" Value="{Binding VisualVerPos}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
和省略号的代码:
<UserControl x:Class="SMT.View.AutoCalibration.AutoCalibrationMarkerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" MouseDown="MarkerMouseDown"
MouseUp="MarkerMouseUp"
MouseMove="MarkerMouseMove" Width="10" Height="10"
Background="Transparent">
<Grid Background="Transparent">
<Line X1="0" Y1="5" X2="10" Y2="5" Fill="{Binding Color}" Stroke="{Binding Color}" StrokeThickness="0.5"/>
<Line X1="5" Y1="0" X2="5" Y2="10" Fill="{Binding Color}" Stroke="{Binding Color}" StrokeThickness="0.5"/>
<Ellipse Width="10" Height="10" Stroke="{Binding Color}" StrokeThickness="0.5" Fill="Transparent"/>
</Grid>
Workaround/Solution
正如@Juan Pablo Garcia Coello在评论中提出的那样,我最终得到了椭圆和线条的不同集合,后者根据需要被清除并重新填充 .