Rifat Murtuza
Rifat Murtuza

Reputation: 1281

Draw a Straight Line In Wpf C#

Hello I'm Drawing a line in my Application . I'm using Caliburn.Micro MVVM Framework . In my DICOM image I'm able to draw a line using Pointer and Calculate distance . I use 3 events MouseDown,MouseMove and MouseUp. I left click to my Mouse and then I move if I release I able to Draw . My problem is when I move my mouse may be it sometimes change direction that time using Graphics.Drawline draw line but when I'm in the last point it should the Straight line . But as I move my Mouse it has the other point the line too that does not belong to this Line . Please see the what I did enter image description here

It should be a starigh line as Sometimes My mouse move the color still at that point .There is a famous DICOM Viewer App Name Radiant Here you can see enter image description here Line is Straight. Here is My code

  <Image    Grid.Row="3"  Grid.Column="2" Grid.ColumnSpan="4" 
                x:Name="DIIMGFINAL"  cal:Message.Attach="[Event MouseDown] = [Action MDownCalCulateDistance($source, $eventArgs)];
                 [Event MouseMove] = [Action MMoveCalCulateDistance($source, $eventArgs)];
                 [Event MouseUp] = [Action MUpCalCulateDistance($source, $eventArgs)]">
    </Image>

And Here is MY C# Code in ViewModel Class. This is MouseDown Event

  public void MDownCalCulateDistance(object sender, System.Windows.Input.MouseEventArgs e)
    {

        if (!(sender is System.Windows.Controls.Image)) return;
        
        _diIMGTemp = DIIMGFINAL;
        if (_firstPoint.X == 0 && _firstPoint.Y == 0)
        {
            System.Windows.Point px1 = e.GetPosition((System.Windows.Controls.Image)sender);

            _firstPoint = px1;
            
        }
        if (_secondPoint.X != 0 && _secondPoint.Y != 0)
        {
            System.Drawing.Bitmap drawbitmap = BitmapImage2Bitmap(DIIMGPrimary);
           
            Graphics g;
            using (g = Graphics.FromImage(drawbitmap))
            {
                g.DrawLine(Pens.Red, Convert.ToInt32(_firstPoint.X), Convert.ToInt32(_firstPoint.Y), Convert.ToInt32(_secondPoint.X), Convert.ToInt32(_secondPoint.Y));
                g.Dispose();
            }

            Convert_BitMap_BitImage(drawbitmap);
            DIIMGFINAL = DIIMGPrimary;

            var geometry = new FrameGeometry(DicomDataSet);
            var patientCoord1 = geometry.TransformImagePointToPatient(new Point2(Convert.ToInt32(_firstPoint.X), Convert.ToInt32(_firstPoint.Y)));
            var patientCoord2 = geometry.TransformImagePointToPatient(new Point2(Convert.ToInt32(_secondPoint.X), Convert.ToInt32(_secondPoint.Y)));
            double distanceInMM = patientCoord1.Distance(patientCoord2);
            DisTanceInMM = distanceInMM;
            //_firstPoint = new System.Windows.Point(0, 0);
            //_secondPoint= new System.Windows.Point(0, 0);
           // _isClicked = false;

        }
    }

This is MouseUp Event ..

 public void MUpCalCulateDistance(object sender, System.Windows.Input.MouseEventArgs e)
    {
        _firstPoint =  new System.Windows.Point(0, 0);
        _secondPoint = new System.Windows.Point(0, 0);
    }

And The last one is Mouse Move Event .

 public void MMoveCalCulateDistance(object sender, System.Windows.Input.MouseEventArgs e)
    {
        if (!(sender is System.Windows.Controls.Image)) return;

        System.Windows.Point px = e.GetPosition((System.Windows.Controls.Image)sender);

        XCoordinate = px.X;
        YCoordinate = px.Y;

        // if (_isClicked == false) return;
        // MousePoint
        if ((_firstPoint.X == 0 && _firstPoint.Y == 0))
        {

            return;
        }
        else
        {
            System.Windows.Point px2 = e.GetPosition((System.Windows.Controls.Image)sender);
            _secondPoint = px2;
            System.Drawing.Bitmap drawbitmap = BitmapImage2Bitmap(DIIMGPrimary);
            Graphics g;
            // g.Clear();
            using (g = Graphics.FromImage(drawbitmap))
            {
                g.DrawLine(Pens.Red, Convert.ToInt32(_firstPoint.X), Convert.ToInt32(_firstPoint.Y), Convert.ToInt32(_secondPoint.X), Convert.ToInt32(_secondPoint.Y));
            }

            Convert_BitMap_BitImage(drawbitmap);
            DIIMGFINAL = DIIMGPrimary;

            var geometry = new FrameGeometry(DicomDataSet);
            var patientCoord1 = geometry.TransformImagePointToPatient(new Point2(Convert.ToInt32(_firstPoint.X), Convert.ToInt32(_firstPoint.Y)));
            var patientCoord2 = geometry.TransformImagePointToPatient(new Point2(Convert.ToInt32(_secondPoint.X), Convert.ToInt32(_secondPoint.Y)));
            double distanceInMM = patientCoord1.Distance(patientCoord2);
            DisTanceInMM = distanceInMM;
        }

    }

Please Help me Thanks in Advance.Sorry For lengthy question .

Upvotes: 0

Views: 1152

Answers (1)

JonasH
JonasH

Reputation: 36639

You should probably not draw directly on the image. This is quite inefficient, and you will also have problems like you have encountered. A better approach would be to create an overlay with lines and other graphics, See the question how to bind lines to a canvas on an example how to do this.

If you put your items control and your image in the same grid the items control should work like an overlay. i.e.

<Grid>
    <Image>
        <!--... -->
    </Image>
    <ItemsControl ItemsSource="{Binding Lines}">
        <!--...-->
    </ItemsControl>
</Grid>

You can use the same approach with an bitmap overlay, but that would be less efficient than letting wpf draw your primitives for you.

Upvotes: 3

Related Questions