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

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

12.10.2025, 02:45. Показов 1801. Ответов 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
1721 / 1511 / 165
Регистрация: 25.07.2015
Сообщений: 2,601
15.10.2025, 18:21
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от wizard41 Посмотреть сообщение
С проблемами:
Затрудняюсь что-то вразумительное сказать.
У меня ( другой комп/другое окружение, просто отсюда скачал) всё стартует без проблем и
в VS и скомпилированный ТС из Debug-а.
0
Эксперт .NET
 Аватар для Rius
13068 / 7629 / 1669
Регистрация: 25.05.2015
Сообщений: 23,183
Записей в блоге: 14
15.10.2025, 18:25
wizard41, это фича буфера обмена в новых виндах. Нельзя просто так к нему обратиться, он почти постоянно чем-то занят. Может, программой, обслуживающей Win+V. Известный workaround - повторять в цикле , пока не прокатит.

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

Добавлено через 1 минуту
Цитата Сообщение от Rius Посмотреть сообщение
Pirat Piratych, попробуйте позицию курсора запоминать и восстананавливать.
блин ...с языка снял, я долго кнопки жмакал
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3392 / 2714 / 574
Регистрация: 04.09.2018
Сообщений: 8,532
Записей в блоге: 3
15.10.2025, 18:28
Цитата Сообщение от Rius Посмотреть сообщение
это фича буфера обмена в новых виндах.
Вот именно. Автор приложения не учел этого и работает с клип-бордом очень слабо.
0
Эксперт .NET
 Аватар для Rius
13068 / 7629 / 1669
Регистрация: 25.05.2015
Сообщений: 23,183
Записей в блоге: 14
15.10.2025, 18:32
Это "заслуга" Microsoft. Напортачили они.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3392 / 2714 / 574
Регистрация: 04.09.2018
Сообщений: 8,532
Записей в блоге: 3
15.10.2025, 18:44
Значит на "новых" виндовс программа ТСа бесполезна..
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3392 / 2714 / 574
Регистрация: 04.09.2018
Сообщений: 8,532
Записей в блоге: 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
2 / 2 / 1
Регистрация: 07.03.2024
Сообщений: 129
15.10.2025, 20:45  [ТС]
Pirat Piratych, попробуйте позицию курсора запоминать и восстананавливать.
Текст копируется нажатием на него.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3392 / 2714 / 574
Регистрация: 04.09.2018
Сообщений: 8,532
Записей в блоге: 3
15.10.2025, 21:15
С позицией курсора совет бесполезный - он у тебя не сработает.
Компоновка для такого подхода неверная.

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

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

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

Логичным выходом в данной ситуации, видимо, будет следующее: в главной форме справа от FlowLayoutPanel добавить еще одну панель для этих нотификаций. Она не будет зависеть от состояния прокрути пунктов меню во FlowLayoutPanel-и. И управлять нотификациями нужно уровнем выше, т.е. из главного окна.
0
2 / 2 / 1
Регистрация: 07.03.2024
Сообщений: 129
15.10.2025, 21:35  [ТС]
Понял.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3392 / 2714 / 574
Регистрация: 04.09.2018
Сообщений: 8,532
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru