Click here to Skip to main content
15,885,309 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am drawing a grid on canvas background. On this canvas, I am labeling the vertical lines of the grid which is drawn on canvas background. Then in the same canvas I have ItemsSource whose Panel is another Canvas and on that canvas I am drawing Line object using Points. Initially the the program is run the vertical lines of the grid are aligned with the points of Line object. The grid's vertical position is drawn at 30th position. And every point on the line is totally aligned to grid's vertical line. When the Mouse Wheel event is fired I want to zoom in the line object. I am using ScaleTransform for that purpose.

In the event handler I am changing the canvas width. Suppose I am using Scale transform with ScaleX equals to 4. This means the new canvas width will be equal to initial width *4. The point which located at 1 on canvas x axis will now be located at position 4 on canvas X axis. So, My 7th point will be at position 28.As we know that the vertical line of the grid is drawn at position 30. And my 8th point will be at position 32. Now I am clueless. I cannot select the position of vertical line of grid at run time. If 30 is selected initially it has to remain 30. While zooming in as I am increasing the width of canvas new Grids are drawn.Max zoom in condition is that there exists only 1 point in 1 grid rectangle. This means the vertical line will be drawn at position 30 so at 30th position the 1st point of line should appear.

What I have tried:

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; }

    }

}

<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>
Posted
Updated 6-Apr-19 11:10am
v2

1 solution

 
Share this answer
 
Comments
hamid18 6-Apr-19 17:25pm    
Thanks for sharing the link. I know for zoom in I have to use ScaleTransform. e.g
ScaleTransform scaleTransform = new ScaleTransform(4, 1);

canvas.RenderTransform = scaleTransform;
canvas.Width = 60 * 4;
MyWidth = canvas.Width;
When I do this initial width is increased to 4 times and every point on canvas is multiplied by 4 along x axis. This means at position 28 along x axis, I will get 7th sample count value. Without zooming this point was present at position 7. Now 8th sample count will come at 32 position. But the vertical line will be drawn at position 30. And I want a discrete sample count value at position 30. I do not want any thing like 7.5 or 7.2 etc. Becaue sample count values are always discrete.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900