我试图在画布上的椭圆之间绘制一组线条。我分两步完成:
' SingleCL'和'积分'都是ObservableCollection< T>
Point-class有四个属性:VisualHorPos,VisualVerPos,CenterHorPos和CenterVerPos,并实现INotifyPropertyChanged。属性表示X,Y,其中' Visual' -properties被调整为当放置在画布上时表示视图的左上角,以便当用鼠标移动时,中心放置在鼠标所在的位置指针是。
这些点按其各自集合中的Y值排序,以便从下到上绘制线条。
为了避免(隐藏)将从0,0绘制到x2的第一行,y2为Point-collection中的第一个点,我使用PriorityBinding使其长度为0因此在实践中隐藏它。
结果是此图像中显示的红色曲折线
在下方添加点(图像方式) - 首先在集合中 - 仅显示省略号,请参见上图中的蓝点。如果我保存数据并从头开始重新加载,则会按预期显示这些行。
在上面添加点(图像方式) - 在集合中的另一个点之后 - 正确绘制线条,但不更新现有线条以考虑新点。
我已经验证了这些点在添加新点和沿Y轴移动时都已正确排序。
也许我对WPF要求太多,但我希望它能够根据ObservableCollection<中的项目顺序从点到点绘制线条。 T> '点数'添加新点时,不仅仅是绑定发生的时间。此外,在移动点时,我预计线条会刷新,因此它们总是根据集合中的顺序从下到上绘制。
我看到它的方式,问题是一旦创建了线,当对象被移动或添加到集合中时,它们不会反弹。有没有办法让ItemsControl重新评估基础ObservableCollection中每个Moved / Added / Removed操作的所有项目< T> ?
"绘图代码"
<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>
解决方法/解决方案
正如@Juan Pablo Garcia Coello在评论中提出的那样,我最终得到了椭圆和线条的不同集合,后者根据需要被清除并重新填充。