使用ObservableCollection和ItemsControl绘制线条和椭圆

时间:2015-04-16 09:52:07

标签: wpf mvvm

我试图在画布上的椭圆之间绘制一组线条。我分两步完成:

  1. 以下XAML中的第一部分,其中ItemsControl绑定到' SingleCL'使用嵌套的ItemsControl可视化线条,绑定到' Points'。
  2. 第二部分,绑定相同的集合,可视化椭圆。
  3. ' SingleCL'和'积分'都是ObservableCollection< T>

    Point-class有四个属性:VisualHorPos,VisualVerPos,CenterHorPos和CenterVerPos,并实现INotifyPropertyChanged。属性表示X,Y,其中' Visual' -properties被调整为当放置在画布上时表示视图的左上角,以便当用鼠标移动时,中心放置在鼠标所在的位置指针是。

    这些点按其各自集合中的Y值排序,以便从下到上绘制线条。

    为了避免(隐藏)将从0,0绘制到x2的第一行,y2为Point-collection中的第一个点,我使用PriorityBinding使其长度为0因此在实践中隐藏它。

    结果是此图像中显示的红色曲折线Results

    在下方添加点(图像方式) - 首先在集合中 - 仅显示省略号,请参见上图中的蓝点。如果我保存数据并从头开始重新加载,则会按预期显示这些行。

    在上面添加点(图像方式) - 在集合中的另一个点之后 - 正确绘制线条,但不更新现有线条以考虑新点。 More points added

    我已经验证了这些点在添加新点和沿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在评论中提出的那样,我最终得到了椭圆和线条的不同集合,后者根据需要被清除并重新填充。

0 个答案:

没有答案