powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Вопрос про скроллинг
1 сообщений из 1, страница 1 из 1
Вопрос про скроллинг
    #40049634
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте!

Есть WidowsForm. На форме присутствуют Panel1 и Button1 .

Функционал формы:
- Если мышкой нажать на изображение, то на него рисуется сверху прямоугольник - фрагмент изображения.
- Курсорными клавишами можно перемещать фрагмент.
- Колесом мыши менять zoom изображения.
C#
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace TestZoomImage
{
    public partial class Form1 : Form
    {
        Image image; //Загруженное изображение
        Image imageZoom; //Изображение после Zoom                   
        Int32 WidthPicture = 6;  //Ширина фрагмента
        Int32 HeightPicture = 6; //Высота фрагмента        
        Int32? PictureBox_X = null; //Последняя координата X фрагмента
        Int32? PictureBox_Y = null; //Последняя координата Y фрагмента
        double zoom = 1.0; //Коэффициент zoom
        double Stride = 0.05; //Шаг для zoom
        Int32? Scroll_X = null; //Позиция бегунка по горизонтали
        Int32? Scroll_Y = null; //Позиция бегунка по вертикали
        PictureBox pictureBox1;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.FormBorderStyle = FormBorderStyle.FixedDialog;           
            pictureBox1 = new PictureBox();
            pictureBox1.Name = "pictureBox1";
            pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
            panel1.AutoScroll = true;
            panel1.Controls.Add(pictureBox1);            
            pictureBox1.MouseDown += new MouseEventHandler(pictureBox1_MouseDown);
            pictureBox1.MouseWheel += new MouseEventHandler(pictureBox1_MouseWheel);
            image = Image.FromFile(@"C:\Users\Acer\Desktop\Image1.png");            
            pictureBox1.Image = image;
            pictureBox1.Width = image.Width;
            pictureBox1.Height = image.Height;
            imageZoom = image;
            pictureBox1.Focus();
        }

        private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
        {
            if (pictureBox1.Image != null)
            {
                zoom = zoom * (1 + Stride * Math.Sign(e.Delta));
                pictureBox1.Width = Convert.ToInt32(image.Width * zoom);
                pictureBox1.Height = Convert.ToInt32(image.Height * zoom);
                ((HandledMouseEventArgs)e).Handled = true;
                Bitmap bmp = new Bitmap(image,
                                        Convert.ToInt32(image.Width * zoom),
                                        Convert.ToInt32(image.Height * zoom));
                Graphics g = Graphics.FromImage(bmp);
                imageZoom = bmp;
                pictureBox1.Image = bmp;
                pictureBox1.Focus();
            }
        }        

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {            

            if (e.X - WidthPicture / 2 >= 0 &&                //Чтобы не выходили за край PictureBox
                e.Y - HeightPicture / 2 >= 0 &&               //с учетом ширины и высоты фрагмента
                e.X + WidthPicture / 2 < pictureBox1.Width && //
                e.Y + HeightPicture / 2 < pictureBox1.Height) //
            {
                PictureBox_X = e.X;
                PictureBox_Y = e.Y;

                Procedure2();
                pictureBox1.Focus();
            }
        }        

        //Движение фрагмента курсорными кнопками
        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (!(PictureBox_X == null || PictureBox_Y == null))
            {
                switch (keyData)
                {
                    case Keys.Right:
                        if (PictureBox_X <= pictureBox1.Image.Width - WidthPicture)
                        {
                            PictureBox_X = PictureBox_X + 1;
                            Procedure1();
                            Procedure2();
                        }
                        return true;

                    case Keys.Left:
                        if (PictureBox_X > WidthPicture / 2)
                        {
                            PictureBox_X = PictureBox_X - 1;
                            Procedure1();
                            Procedure2();
                        }
                        return true;

                    case Keys.Up:
                        if (PictureBox_Y > HeightPicture / 2)
                        {
                            PictureBox_Y = PictureBox_Y - 1;
                            Procedure1();
                            Procedure2();
                        }
                        return true;

                    case Keys.Down:
                        if (PictureBox_Y <= pictureBox1.Image.Height - HeightPicture)
                        {
                            PictureBox_Y = PictureBox_Y + 1;
                            Procedure1();
                            Procedure2();
                        }
                        return true;
                }
            }
            return base.ProcessDialogKey(keyData);
        }

        //Проверяет выходит ли фрагмент за пределы видимости
        //Если да - сдвигает бегунок в соответствующую сторону, чтобы фрагмент был полностью виден
        private void Procedure1()
        {
            
        }

        //Процедура, которая вставляет прямоугольник на изображение.
        private void Procedure2()
        {
            //Получаем прямоугольник
            Rectangle cloneRect = new Rectangle((int)PictureBox_X - WidthPicture / 2,
                                                (int)PictureBox_Y - HeightPicture / 2,
                                                 WidthPicture,
                                                 HeightPicture);
            Bitmap myBitmap = new Bitmap(imageZoom);
            PixelFormat format = myBitmap.PixelFormat;
            Bitmap newBitmapForForm = new Bitmap(imageZoom);
            using (Graphics g = Graphics.FromImage(newBitmapForForm))
            {
                g.DrawRectangle(new Pen(Color.Black, 1), cloneRect);
                g.Dispose();
            }
            pictureBox1.Image = newBitmapForForm;
        }        

        private void button1_Click(object sender, EventArgs e)
        {
            //Какая то процедура

            pictureBox1.Focus(); //Если это убрать, то бегунок не теряет свою позицию, но не будет работать zoom

            panel1.HorizontalScroll.Value = (int)Scroll_X;
            panel1.VerticalScroll.Value = (int)Scroll_Y;
        }

        //Получаем новые значения скроллинга после изменения
        private void panel1_Scroll(object sender, ScrollEventArgs e)
        {
            if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)
            {
                Scroll_X = e.OldValue;
            }
            else
            {
                Scroll_Y = e.OldValue; // Здесь почему то e.OldValue равен нулю
            }            
        }
        
    }
}

Здесь возникают вопросы:

1. Но если прокрутить бегунок (и горизонтально, и вертикально), нажать мышкой и потом нажать на button, то вертикальный бегунок фактически занял исходную позицию, но изображение по вертикали на месте и почему то значение e.OldValue равно нулю.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
        private void button1_Click(object sender, EventArgs e)
        {
            //Какая то процедура

            pictureBox1.Focus(); //Если это убрать, то бегунок не теряет свою позицию, но не будет работать zoom

            panel1.HorizontalScroll.Value = (int)Scroll_X;
            panel1.VerticalScroll.Value = (int)Scroll_Y;
        }

Почему так? Как правильно написать? Тут еще дополнительно надо учитывать, чтобы значение 'Value' лежало в диапазоне от 'minimum' до 'maximum'.

2. Нужно сделать так, если фрагмент находится за пределы видимости - бегунок автоматически перемещался в соответствующую сторону, чтобы фрагмент был виден целиком. Подскажите, как это можно сделать?
...
Рейтинг: 0 / 0
1 сообщений из 1, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Вопрос про скроллинг
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]