在WPF中将网格垂直线与Line对象的点对齐

时间:2019-04-04 10:34:47

标签: c# wpf scaletransform

我正在画布背景上绘制网格。在此画布上,我标记了在画布背景上绘制的网格的垂直线。然后在同一画布中,我有ItemsSource,其Panel是另一个Canvas,并且在该画布上,我使用Points绘制Line对象。最初,程序在运行,网格的垂直线与Line对象的点对齐。网格的垂直位置在第30个位置绘制。并且线上的每个点都与网格的垂直线完全对齐。触发“鼠标滚轮”事件后,我要放大线对象。我为此使用ScaleTransform。在事件处理程序中,我正在更改画布宽度。假设我在ScaleX等于4的情况下使用Scale变换。这意味着新的画布宽度将等于初始宽度* 4。现在,在画布x轴上位于1的点将位于画布x轴上的位置4。因此,我的第7点将位于位置28。众所周知,网格的垂直线是在位置30处绘制的。而我的第8点将在位置32处绘制。现在我毫无头绪。我无法在运行时选择网格垂直线的位置。如果最初选择30,则必须保留30。在放大的同时,随着我增加画布的宽度,将绘制新的Grid。最大放大条件是1个矩形中仅存在1个点。这意味着垂直线将在位置30处绘制,因此在第30个位置应显示该线的第一个点。

C#

namespace CanvasWidthChecker
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        double scaleFactor = 1;
        double deltaDistance = 1;
        ulong totalSamples;
        const double maximumDeltaDistance = 30;
        double maximumScale = maximumDeltaDistance;
        List<Line> verticalLines = new List<Line>();

        private double initialWidth;

        public double InitialWidth
        {
            get { return initialWidth; }
            set { initialWidth = value; }
        }


        private double myWidth= 60;

        public double MyWidth
        {
            get { return myWidth; }
            set
            {
                myWidth = value;
                OnPropertyChanged("MyWidth");
            }
        }
        private void Line_Loaded(object sender, RoutedEventArgs e)
        {
            Line line = sender as Line;

            if (line.Y1 != line.Y2)
            {
                verticalLines.Add(line);
            }
        }
        private ObservableCollection<Graph> lines;

        public ObservableCollection<Graph> Lines
        {
            get { return lines; }
            set { lines = value; }
        }
        private ObservableCollection<MyLabel> myList;
        public ObservableCollection<MyLabel> MyList
        {
            get { return myList; }
            set
            {
                myList = value;
                OnPropertyChanged("MyList");
            }
        }

        private ulong samplecount;

        public ulong Samplecount
        {
            get { return samplecount; }
            set { samplecount = value; }
        }

        public MainWindow()
        {
            InitializeComponent();
            this.Samplecount = 60;
            this.InitialWidth = Samplecount;
            MyList = new ObservableCollection<MyLabel>();
            MyList.Add(new MyLabel() { ContentData = "0" });
            MyList.Add(new MyLabel() { ContentData = "30" });
            Lines = new ObservableCollection<Graph>();
            Lines.Add(new Graph() { From = new Point(0,22), To = new Point (18,22) });
            Lines.Add(new Graph() { From = new Point(18-0.5, 22), To = new Point(18-0.5, 7) });
            Lines.Add(new Graph() { From = new Point(18, 7), To = new Point(24, 7) });
            Lines.Add(new Graph() { From = new Point(24-0.5, 7), To = new Point(24-0.5, 22) });
            Lines.Add(new Graph() { From = new Point(24, 22), To = new Point(60, 22) }); // Samplecount  was 60

            DataContext = this;


        }

        private void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            Canvas canvas = (Canvas)sender;
            e.Handled = true;
            double deltaValue = (e.Delta > 0) ? 1 : -1;
            deltaDistance += deltaValue;
            if(deltaDistance<2)
            {
                deltaDistance = 1;
            }
            ScaleTransform scaleTransform = new ScaleTransform(deltaDistance, 1);
            canvas.RenderTransform = scaleTransform;
            verticalLines.ForEach(x => {
                x.RenderTransformOrigin = new Point(1, 1);

                x.RenderTransform = new ScaleTransform(1 / scaleTransform.ScaleX, 1 / scaleTransform.ScaleY);
            });
            canvas.Width = 60 * deltaDistance;
            MyWidth = canvas.Width;
        }

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }
    }

    public class Graph
    {
        private Point from;

        public Point From
        {
            get { return from; }
            set { from = value; }
        }
        private Point to;

        public Point To
        {
            get { return to; }
            set { to = value; }
        }

    }
    public class MyLabel
    {
        public string ContentData { get; set; }

    }

}

XAML

 <ScrollViewer  Name="scrollViewer" HorizontalScrollBarVisibility="Auto"  Margin="10,10,0,10" Padding="0,0,10,0"
            Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualWidth}"
                       Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}"     >
        <Canvas  x:Name="back_canvas"  Width="{Binding MyWidth}" Height="60" 

              VerticalAlignment="Top" HorizontalAlignment="Left"  Margin="30,30,10,20"   >
            <Canvas.Background>
                <DrawingBrush TileMode="Tile" Viewport="0,0,30,30"  ViewportUnits="Absolute">

                    <DrawingBrush.Drawing>
                        <GeometryDrawing>
                            <GeometryDrawing.Geometry>
                                <RectangleGeometry Rect="0,0,30,30"/>
                            </GeometryDrawing.Geometry>
                            <GeometryDrawing.Pen>
                                <Pen Brush="Gray" Thickness="1"/>
                            </GeometryDrawing.Pen>
                        </GeometryDrawing>
                    </DrawingBrush.Drawing>
                </DrawingBrush>
            </Canvas.Background>
            <ItemsControl ItemsSource="{Binding MyList}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Name="horizontalLabels" Orientation="Horizontal"/>
                   </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock      Text="{Binding ContentData}"  Canvas.Left="10" Canvas.Top="0"

                                         Width="27" 
                                         Height="30"  FontSize="12"
                                         Margin="0,0,3,0">
                        </TextBlock>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

            <ItemsControl ItemsSource="{Binding Lines}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas  Height="30" Margin="0,30,0,0"  Background="Transparent"  Name="front_canvas" ClipToBounds="True" 
                                    PreviewMouseWheel="OnPreviewMouseWheel"
                                      Width="{Binding MyWidth, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
                                      />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>

                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Line   X1="{Binding From.X , Mode=TwoWay}" Y1="{Binding From.Y, Mode=TwoWay}" Stretch="None"
                            X2="{Binding To.X, Mode=TwoWay}" Y2="{Binding To.Y, Mode=TwoWay}" 
                            Stroke="OrangeRed" StrokeThickness="1" 

                                  Loaded="Line_Loaded"
                            />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>

            </ItemsControl>


            </Canvas>



    </ScrollViewer>
</Window>

0 个答案:

没有答案
相关问题