Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
3 / 3 / 2
Регистрация: 07.03.2024
Сообщений: 154

ScrollBar почему-то после копирования текста возвращается в начало

12.10.2025, 02:45. Показов 2161. Ответов 30
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
ScrollBar почему-то после копирования текста возвращается в начало, из-за чего не очень удобно постоянно его двигать. Пытался как-то исправить, но не вышло. Может быть Вы, дорогие форумчане подскажите в чем ошибка? Еще почему-то сам ScrollBar появляется на панельке, а не рядом, из-за чего красота панельки малость страдает.
Код панелек, в которых этот ScrollBar работает.
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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using Newtonsoft.Json.Linq;
using System.Drawing.Drawing2D;
 
namespace WindowsFormsApplication1
{
    public partial class UC : UserControl
    {
        bool b = false;
        int H = 23;
        string myTag;
        string tmpTag = "";
        readonly Color Color1 = Color.White; // Цвет шрифта подменю на правой панели
        readonly Color Color2 = Color.White; // Цвет шрифта подменю на правой панели (активный)
        readonly Color Color3 = Color.OrangeRed; // Цвет шрифта подменю на правой панели (неактивный)
        readonly Color Color4 = Color.Brown; // Цвет шрифта подменю на правой панели (неактивный)
        readonly Color Color5 = Color.Transparent;
 
        private System.Windows.Forms.Timer animationTimer;
        private int targetHeight;
        private float easingFactor = 0.1f; // Фактор замедления анимации (0.05 - медленнее, 0.2 - быстрее)
        private int borderRadius = 10; // Радиус скругления углов (настраиваемый, например, 5-20)
 
        // Новые поля для уведомлений
        private List<Label> activeNotifications = new List<Label>();
        private Dictionary<Label, System.Windows.Forms.Timer> hideTimers = new Dictionary<Label, System.Windows.Forms.Timer>();
        private Dictionary<Label, System.Windows.Forms.Timer> hideAnimationTimers = new Dictionary<Label, System.Windows.Forms.Timer>(); // Добавлено для анимации скрытия
        private System.Windows.Forms.Timer slideTimer;
        private System.Windows.Forms.Timer repositionAnimationTimer; // Новый таймер для плавного перепозиционирования
        private Dictionary<Label, int> targetYPositions = new Dictionary<Label, int>(); // Целевые Y-позиции для анимации
        private int notificationHeight = 25; // Высота уведомления для позиционирования
 
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            GraphicsPath path = new GraphicsPath();
            path.AddArc(0, 0, borderRadius, borderRadius, 180, 90);
            path.AddArc(Width - borderRadius, 0, borderRadius, borderRadius, 270, 90);
            path.AddArc(Width - borderRadius, Height - borderRadius, borderRadius, borderRadius, 0, 90);
            path.AddArc(0, Height - borderRadius, borderRadius, borderRadius, 90, 90);
            path.CloseFigure();
            this.Region = new Region(path);
            // Рисуем фон, чтобы избежать артефактов
            using (SolidBrush brush = new SolidBrush(this.BackColor))
            {
                e.Graphics.FillPath(brush, path);
            }
            path.Dispose();
        }
 
        public UC(string caption, string tag, StructDataForUC[] arr)
        {
            InitializeComponent();
            this.DoubleBuffered = true; // Предотвращает мерцание при анимации
            Color5 = this.BackColor;
            lblCaption.ForeColor = Color1;
            lblCaption.Text = caption;
            lblCaption.Font = new Font("Arial Black", 10, FontStyle.Bold);
            this.Tag = tag;
            myTag = tag;
            FillUC(arr);
            this.Visible = false;
 
            button1.FlatStyle = FlatStyle.Flat;
            button1.FlatAppearance.BorderSize = 0;
            button1.BackColor = this.BackColor; // или нужный цвет фона
            button1.FlatAppearance.MouseOverBackColor = this.BackColor; // чтобы при наведении не менялся цвет
            button1.FlatAppearance.MouseDownBackColor = this.BackColor; // чтобы при нажатии не менялся цвет
 
            // Инициализация таймера для анимации
            animationTimer = new System.Windows.Forms.Timer();
            animationTimer.Interval = 25; // 25 мс для плавности (~100 FPS)
            animationTimer.Tick += AnimationTimer_Tick;
 
            // Таймер для анимации уведомлений
            slideTimer = new System.Windows.Forms.Timer();
            slideTimer.Interval = 25; // 25 мс для плавной анимации
            slideTimer.Tick += SlideTimer_Tick;
 
            // Таймер для плавного перепозиционирования уведомлений
            repositionAnimationTimer = new System.Windows.Forms.Timer();
            repositionAnimationTimer.Interval = 15; // 15 мс для плавности
            repositionAnimationTimer.Tick += RepositionAnimationTimer_Tick;
 
            // Устанавливаем начальную высоту
            this.Height = button1.Height;
        }
 
        // Обработчик для отрисовки скруглённого фона уведомления и текста
        private void NotificationLabel_Paint(object sender, PaintEventArgs e)
        {
            Label lbl = sender as Label;
            if (lbl == null) return;
            int radius = 10; // Радиус скругления углов
            Rectangle rect = new Rectangle(0, 0, lbl.Width, lbl.Height);
            using (GraphicsPath path = RoundedRect(rect, radius))
            {
                e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                using (SolidBrush brush = new SolidBrush(Color.White)) // Белый фон
                {
                    e.Graphics.FillPath(brush, path);
                }
                using (Pen pen = new Pen(Color.Gray)) // Серая рамка
                {
                    e.Graphics.DrawPath(pen, path);
                }
                // Рисуем текст вручную
                using (SolidBrush textBrush = new SolidBrush(lbl.ForeColor))
                {
                    e.Graphics.DrawString(lbl.Text, lbl.Font, textBrush, lbl.Padding.Left, lbl.Padding.Top);
                }
            }
        }
 
        // Метод для создания GraphicsPath с закруглёнными углами
        private GraphicsPath RoundedRect(Rectangle bounds, int radius)
        {
            int diameter = radius * 2;
            GraphicsPath path = new GraphicsPath();
 
            path.StartFigure();
            path.AddArc(bounds.Left, bounds.Top, diameter, diameter, 180, 90); // Верхний левый угол
            path.AddArc(bounds.Right - diameter, bounds.Top, diameter, diameter, 270, 90); // Верхний правый
            path.AddArc(bounds.Right - diameter, bounds.Bottom - diameter, diameter, diameter, 0, 90); // Нижний правый
            path.AddArc(bounds.Left, bounds.Bottom - diameter, diameter, diameter, 90, 90); // Нижний левый
            path.CloseFigure();
 
            return path;
        }
 
        private void FillUC(StructDataForUC[] arr)
        {
            // H =  arr.Length * 20 + button1.Height ;
            int maxH = button1.Height;
            int lastTop = arr.Length * 20;
            for (int i = 0; i < arr.Length; i++)
            {
                Label l = new Label() { Tag = arr[i].mTag.ToString(), Text = arr[i].text };
                this.Controls.Add(l);
                l.Font = new Font("Arial", 10, FontStyle.Bold);
                l.Top = button1.Height + 2 + l.Height * i + 20;
                l.Left = 20;
                l.AutoSize = true;
                l.Text = arr[i].text;
                TT.SetToolTip(l, l.Text);
                if (arr[i].Copyable)
                {
                    l.MouseUp += new System.Windows.Forms.MouseEventHandler(Lab_MouseUp);
                    l.ForeColor = Color2;
                    l.Cursor = Cursors.Hand;
                }
                else
                    l.ForeColor = Color4;
                //H = l.Top + l.Height + 20 ;
                if (maxH < l.Height) maxH = l.Height;
                if (lastTop < l.Top) lastTop = l.Top;
                l.BackColor = Color5;
                //  l.ContextMenuStrip = CMS;
            }
            H = lastTop + maxH + 10;
            this.Height = b ? H : button1.Height;
        }
Также прилагается видео, где показаны проблемы.
Вложения
Тип файла: mp4 Видео 12-10-2025 044320.mp4 (1.68 Мб, 28 просмотров)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
12.10.2025, 02:45
Ответы с готовыми решениями:

Если возвращается переменная ссылочного типа, то возвращается объект или просто ссылка
Почему-то авторы всегда акцентируют внимание на передачу параметров в функцию, а на возврат не...

После шифрования возвращается исходный текст
надо зашифровать и расшифровать строку по алгоритму Виженера. на бумажке код работает(ну...

DataGridView1_CellContentClick: почему иногда возвращается название кнопки
Быть может я плохо описал сначала !! На datagriedview1 присутствуют две кнопки Есть событие ...

30
1800 / 1782 / 173
Регистрация: 25.07.2015
Сообщений: 2,899
15.10.2025, 18:21
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от wizard41 Посмотреть сообщение
С проблемами:
Затрудняюсь что-то вразумительное сказать.
У меня ( другой комп/другое окружение, просто отсюда скачал) всё стартует без проблем и
в VS и скомпилированный ТС из Debug-а.
0
Эксперт .NET
 Аватар для Rius
13375 / 7830 / 1695
Регистрация: 25.05.2015
Сообщений: 23,833
Записей в блоге: 14
15.10.2025, 18:25
wizard41, это фича буфера обмена в новых виндах. Нельзя просто так к нему обратиться, он почти постоянно чем-то занят. Может, программой, обслуживающей Win+V. Известный workaround - повторять в цикле , пока не прокатит.

Pirat Piratych, попробуйте позицию курсора запоминать и восстананавливать.
1
1800 / 1782 / 173
Регистрация: 25.07.2015
Сообщений: 2,899
15.10.2025, 18:28
Цитата Сообщение от Pirat Piratych Посмотреть сообщение
чтобы решить трабл.
Это не трабл. Форма перерисовывается , т.е. приходит в начальное состояние ,после добавления контрола.
Сами проверьте в дебаге построчно.
Или смириться или костылить.
Например фиксировать положение курсора и после перерисовки , т.е. после добавления контрола,
возвращаться на сохраненную позицию... ну это так ,в лоб, в качестве бреда ))

Добавлено через 1 минуту
Цитата Сообщение от Rius Посмотреть сообщение
Pirat Piratych, попробуйте позицию курсора запоминать и восстананавливать.
блин ...с языка снял, я долго кнопки жмакал
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3457 / 2778 / 575
Регистрация: 04.09.2018
Сообщений: 8,734
Записей в блоге: 3
15.10.2025, 18:28
Цитата Сообщение от Rius Посмотреть сообщение
это фича буфера обмена в новых виндах.
Вот именно. Автор приложения не учел этого и работает с клип-бордом очень слабо.
0
Эксперт .NET
 Аватар для Rius
13375 / 7830 / 1695
Регистрация: 25.05.2015
Сообщений: 23,833
Записей в блоге: 14
15.10.2025, 18:32
Это "заслуга" Microsoft. Напортачили они.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3457 / 2778 / 575
Регистрация: 04.09.2018
Сообщений: 8,734
Записей в блоге: 3
15.10.2025, 18:44
Значит на "новых" виндовс программа ТСа бесполезна..
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3457 / 2778 / 575
Регистрация: 04.09.2018
Сообщений: 8,734
Записей в блоге: 3
15.10.2025, 18:55
Pirat Piratych,
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        [DllImport("User32")]
        public static extern bool OpenClipboard(IntPtr hWndNewOwner);
        [DllImport("User32")]
        public static extern bool CloseClipboard();
 
        [DllImport("User32")]
        public static extern bool EmptyClipboard();
 
        [DllImport("User32")]
        public static extern bool IsClipboardFormatAvailable(int format);
 
        [DllImport("User32")]
        public static extern IntPtr GetClipboardData(int uFormat);
 
        [DllImport("User32", CharSet = CharSet.Unicode)]
        public static extern IntPtr SetClipboardData(int uFormat, IntPtr hMem);
C#
1
2
3
4
5
6
7
8
9
10
11
        public static void SetText(string text)
        {
            if (!OpenClipboard(IntPtr.Zero))
            {
                SetText(text);
                return;
            }
            EmptyClipboard();
            SetClipboardData(13, Marshal.StringToHGlobalUni(text));
            CloseClipboard();
        }
C#
1
2
3
4
5
6
7
8
9
        private void btnClipCopy_Click(object sender, EventArgs e)
        {
            SetText(tbClip.Text);
        }
 
        private void btnClipPaste_Click(object sender, EventArgs e)
        {
            tbClip.Text = Clipboard.GetText();
        }
Миниатюры
ScrollBar почему-то после копирования текста возвращается в начало  
0
3 / 3 / 2
Регистрация: 07.03.2024
Сообщений: 154
15.10.2025, 20:45  [ТС]
Pirat Piratych, попробуйте позицию курсора запоминать и восстананавливать.
Текст копируется нажатием на него.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3457 / 2778 / 575
Регистрация: 04.09.2018
Сообщений: 8,734
Записей в блоге: 3
15.10.2025, 21:15
С позицией курсора совет бесполезный - он у тебя не сработает.
Компоновка для такого подхода неверная.

1. Юзерконтрол с текстами (пунктами) находится внутри FlowLayoutPanel, и если он больше чем высота окна, то прокрутка появляется у FlowLayoutPanel, т.е. у родительского контрола.
А это значит, что управлять прокруткой нужно уровнем выше, а не из UC, которые в ней появляются.

2. Новые лейблы "Скопировано" ты помещаешь в этот же самый UC, начиная сверху. Даже если п.1 выполнить (сохранять позицию скролла), то эти лейблы не будет видно, пока не прокрутишь в самый верх.

3. Не нужно обновлять FlowLayoutPanel каждый раз при щелчке на копируемом итеме. Именно это заставляет его отрисовываться снова с прокруткой вверху.

Логичным выходом в данной ситуации, видимо, будет следующее: в главной форме справа от FlowLayoutPanel добавить еще одну панель для этих нотификаций. Она не будет зависеть от состояния прокрути пунктов меню во FlowLayoutPanel-и. И управлять нотификациями нужно уровнем выше, т.е. из главного окна.
0
3 / 3 / 2
Регистрация: 07.03.2024
Сообщений: 154
15.10.2025, 21:35  [ТС]
Понял.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3457 / 2778 / 575
Регистрация: 04.09.2018
Сообщений: 8,734
Записей в блоге: 3
15.10.2025, 22:02
Что-то типа такого:

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.10.2025, 22:02

Switch-case: Не могу понять почему не весь код в методе возвращается
подскажите пожалуйста... Не могу понять почему пишет что не весь код в методе возвращается. Я...

В какой поток возвращается управление после Task.Run() и как работает ConfigureAwait?
Для теста написал такой простой метод: static async Task TstMethod() { for...

Как сделать чтобы ScrollBar увеличивал или уменьшал текст?
Как сделать что бы с помощью hScrollBar1 увеличивался или уменьшался текст в richTextBox1? час не...

Сохранение позиции Scrollbar после добавления элемента
Здравствуйте. У меня на форме есть элемент textbox со скролл баром. Пользователь вводит слова,...

ScrollBar после создания формы
Есть форма, на ней текстбокс с текстом и скроллбаром. Вопрос: как &quot;активировать&quot; скроллбар? При...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
31
Ответ Создать тему
Новые блоги и статьи
сукцессия 30. Фосфорный и азотный замки по "честному" закону лимитирования Либиха
anaschu 16.07.2026
Основные достижения за последние дни 1. Механизм отложенного высвобождения фосфора Добавлен специальный пул для медленного разложения меланизированных гиф ЕСМ Реализована разная скорость. . .
Запрет пометки на удаление и отмены проведения
Maks 16.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "ПутевойЛист" разработанного в КА2. Задача: запретить помечать на удаление и отменять проведения путевого листа при условии, если он сдан. . .
Как надо было делать правильно - вообще не слушать ИИ, его дело - текст.
Hrethgir 15.07.2026
А вообще надо было делать не так, чтобы не исправлять ошибку https:/ / www. cyberforum. ru/ blogs/ 223907/ 10996. html , правильно было : удалил кнопку, а потом добавил её. Всё это стресс конечно. Почему?. . .
Знаете, от чего появляется стресс?
kumehtar 15.07.2026
Стресс появляется оттого, что вы, зная как поступить правильно, делаете наоборот. Ларри Уингет
Нас бьют, а мы крепчаем? Какая чушь!
kumehtar 15.07.2026
Вот это вот бытующее мнение, что человек меняется только под действием проблем, всегда считал вредоносным. Поверь, от проблем у людей появляются не изменения, а нервное расстройство и ПТСР. А. . .
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru