Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.86/21: Рейтинг темы: голосов - 21, средняя оценка - 4.86
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
UWP

DragPositionBehavior при быстром перемещении курсора теряется его позиция

21.11.2021, 17:34. Показов 4708. Ответов 55
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Я написал простой Behavior для того, чтобы перемещать элемент внутри Canvas.

Элемент перемещается, всё хорошо, пока я не захватываю элемент за край.
В таком случае елемент легко может потерять текущее местоположение курсора, но OnElementPointerReleased не сработает, а следовательно и не сработает отписка от OnMove.
Это значит, что когда курсор покидает элемент, при том, что до этого я на него нажал, элемент не видит куда я перемещаю курсор, не видит отжал ли я кнопку мыши.
Если я верну курсор мыши обратно в элемент, он продолжит функционировать должным образом.




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
    public partial class DragPositionBehavior : DependencyObject, IBehavior
    {
        public DependencyObject AssociatedObject{ get; set; }
 
        private Point prevPoint;
        private int pointerId = -1;
 
 
        public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(nameof(Command), typeof(ICommand), typeof(DragPositionBehavior), new PropertyMetadata(null));
        public ICommand Command { get => (ICommand)GetValue(CommandProperty); set => SetValue(CommandProperty, value); }
 
 
        public static readonly DependencyProperty ZoomFactorProperty = DependencyProperty.Register(nameof(ZoomFactor), typeof(double), typeof(DragPositionBehavior), new PropertyMetadata(0));
        public double ZoomFactor { get => (double)GetValue(ZoomFactorProperty); set => SetValue(ZoomFactorProperty, value); }
 
 
        public static readonly DependencyProperty BaseElementProperty = DependencyProperty.Register(nameof(BaseElement), typeof(Panel), typeof(DragPositionBehavior), new PropertyMetadata(new Grid()));
        public Panel BaseElement { get => (Panel)GetValue(BaseElementProperty); set => SetValue(BaseElementProperty, value); }
 
 
        #region Life circle
        public void Attach(DependencyObject associatedObject)
        {
            if ((associatedObject != AssociatedObject) && !Windows.ApplicationModel.DesignMode.DesignModeEnabled)
            {
                AssociatedObject = associatedObject;
                var element = AssociatedObject as FrameworkElement;
                if (element != null)
                {
                    element.PointerPressed += OnElementPointerPressed;
                    element.PointerReleased += OnElementPointerReleased;
                }
            }
        }
 
        public void Detach()
        {
            var element = AssociatedObject as FrameworkElement;
 
            if (element is not null)
            {
                element.PointerPressed -= OnElementPointerPressed;
                element.PointerReleased -= OnElementPointerReleased;
            }
 
            if (BaseElement is not null)
            {
                BaseElement.PointerMoved -= OnMove;
            }
 
            BaseElement = null;
            AssociatedObject = null;
        }
        #endregion
 
        #region Handle pointer input
        private void OnElementPointerPressed(object sender, PointerRoutedEventArgs e)
        {
            var element = sender as FrameworkElement;
 
            if (element == null)
                return;
 
            if (!(element.RenderTransform is TranslateTransform))
                element.RenderTransform = new TranslateTransform();
 
            BaseElement.PointerMoved += OnMove;
 
            prevPoint = e.GetCurrentPoint(BaseElement).Position;
            pointerId = (int)e.Pointer.PointerId;
        }
 
        private void OnElementPointerReleased(object sender, PointerRoutedEventArgs e)
        {
            if (e.Pointer.PointerId != pointerId)
                return;
 
            var element = sender as FrameworkElement;
            if (element == null)
                return;
 
            BaseElement.PointerMoved -= OnMove;
            pointerId = -1;
 
            Point position = e.GetCurrentPoint(element).Position;
 
            if (Command.CanExecute(position))
                Command.Execute(position);
        }
 
        private void OnMove(object o, PointerRoutedEventArgs e)
        {
            var zommFactor = ZoomFactor;
            var element = AssociatedObject as FrameworkElement;
 
            if (e.Pointer.PointerId != pointerId || element is null)
                return;
 
            var pos = e.GetCurrentPoint(BaseElement).Position;
            ((TranslateTransform)element.RenderTransform).X += (pos.X - prevPoint.X) / zommFactor;
            ((TranslateTransform)element.RenderTransform).Y += (pos.Y - prevPoint.Y) / zommFactor;
            prevPoint = pos;
        }
        #endregion
    }

BaseElement нужен в тех случаях, когда у меня Parent может быть этот же элемент. Например когда там будет Grid в Grid'е.
XML
1
2
3
4
5
6
7
8
9
        <Canvas x:Name="baseElement" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
 
            <Border Margin="100,100,0,0" Width="250" Height="400" Background="White" AllowDrop="True">
                <interactivity:Interaction.Behaviors>
                    <behaviors:DragPositionBehavior Command="{Binding TestBoard.SavePositionCommand}" BaseElement="{Binding ElementName=baseElement}" ZoomFactor="1"/>
                </interactivity:Interaction.Behaviors>
            </Border>
 
        </Canvas>
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.11.2021, 17:34
Ответы с готовыми решениями:

При быстром перемещении окон и открытии меню приложение тормозит ubuntu
Последняя версия.

Позиция курсора и его форма
Есть задание, нужно сдвинуть позицию курсора на 300 пикселей вправо и 100 пикселей вниз, а также изменить форму курсора. Есть код на ...

Выделение при перемещении курсора в StringGrid
Всем добрый день. В таблице Stringgrid реализовал Drag&amp;Drop на перетаскивание строк. Так вот, для удобства пользования этой функцией...

55
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16152 / 11273 / 2890
Регистрация: 21.04.2018
Сообщений: 33,147
Записей в блоге: 2
13.12.2021, 12:12
Студворк — интернет-сервис помощи студентам
Такого типа как Behavior обрабатываемого WPF нет.
Behavior - это тоже AP свойство, но уже реализованное в библиотеке.

Немного подробнее в этой теме: AP свойство-коллекция для биндинга всплывающих RoutedComman к командам VM
1
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
13.12.2021, 12:13  [ТС]
То есть таким образом я из статического метода могу вызвать не статический.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16152 / 11273 / 2890
Регистрация: 21.04.2018
Сообщений: 33,147
Записей в блоге: 2
13.12.2021, 12:14
Цитата Сообщение от limeniye Посмотреть сообщение
class DragPosition
Это что за класс?
Откуда он появился?

Добавлено через 22 секунды
Цитата Сообщение от limeniye Посмотреть сообщение
То есть таким образом я из статического метода могу вызвать не статический.
Если есть ссылка на экземпляр.
0
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
13.12.2021, 12:17  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Это что за класс?
Откуда он появился?
Я просто переименовал тип, так как это теперь не Behavior.

И тперь пытаюсь из статического метода вызвать метод для инициализации.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16152 / 11273 / 2890
Регистрация: 21.04.2018
Сообщений: 33,147
Записей в блоге: 2
13.12.2021, 12:47
Цитата Сообщение от limeniye Посмотреть сообщение
Я просто переименовал тип, так как это теперь не Behavior.
А... Понял.
Мне сегодня некогда.
Повозитесь сами.
Возможно завтра смогу посмотреть детальнее.

Добавлено через 3 минуты
Но вы его наследовали от DependecyObject?
0
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
13.12.2021, 13:19  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Но вы его наследовали от DependecyObject?
Да, оставил, ибо методы по типу GetValue не будут работать.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16152 / 11273 / 2890
Регистрация: 21.04.2018
Сообщений: 33,147
Записей в блоге: 2
13.12.2021, 13:35
Цитата Сообщение от limeniye Посмотреть сообщение
Да, оставил, ибо методы по типу GetValue не будут работать.
Свойство BaseParent используется для определения относительных координат перемещения мыши.
Для этого не обязательно использовать независимый элемент.
Так как нужны относительные координаты по отношению к неподвижному (в окне) элементу, то можэно их определять по отношению к самому Окну.
В WPF для этого используется GetPosition(null) - возможно в UWP.
Но там была проблема (насколько помню) при выходе курсора за границу элемента (захват за край).
И подписка на MouseUp нужна по отношению к более высокому контейнеру.
Можно динамически подыматься то первой панели, или до Page? или доя Window.
Можно под BaseParent сделать отдельное AP-свойство.

То есть смысла оставлять в DragPosition это свойство нет.

Свойство ZoomFactor - даже не представляю где оно может отличаться от 1.
Но даже если нужно, теперь есть внешние привязки которые можно использовать с конвертером.
Поэтому тоже смысла в этом свойстве нет.

И в итоге у вас не останется в DragPosition DP-свойств.
Будут только AP-свойства.
А для них можно использовать обычный или даже статический класс.
1
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
13.12.2021, 17:19  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Свойство ZoomFactor - даже не представляю где оно может отличаться от 1.
Я передаю из ScrollView значение его зума, для того, чтобы потом сделать просчёт:
C#
1
2
SetOffsetX(AssociatedUIElement, GetOffsetX(AssociatedUIElement) + (pos.X - prevPoint.X) / zommFactor);
SetOffsetY(AssociatedUIElement, GetOffsetY(AssociatedUIElement) + (pos.Y - prevPoint.Y) / zommFactor);
Это нужно для того, чтобы можно было приближать или отдалять элементы.

Добавлено через 43 минуты
Элд Хасп, удалил Behavior. Сделал AP для BaseParent и ZoomFactor. Не делал обработку если BaseParent -- null, так как до этого момента у меня уже всё идёт не по плану.

Основная проблема -- полное непонимание работы с статическими AP и не статическими, приватными методами/полями.
Для того, чтобы у меня хотябы сбилдился проект, пришлось сделать поля статическими (что неправильно).
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16152 / 11273 / 2890
Регистрация: 21.04.2018
Сообщений: 33,147
Записей в блоге: 2
13.12.2021, 19:29
Цитата Сообщение от limeniye Посмотреть сообщение
Я передаю из ScrollView значение его зума, для того, чтобы потом сделать просчёт:
Чё-то мне кажется вы мудрите.
Перемещение же элементов происходит в экранных координатах.
Зум здесь не должен играть роль.
Если у вас в Модели (SomeType) есть зум и нужно его учитывать при привязке к его свойствам Position, то это нужно делать в конвертере привязки.
А то получается у вас первичная привязка без зума, а смещение с зумом.
Мне, кажется, какая-то каша выйдет.

Цитата Сообщение от limeniye Посмотреть сообщение
Для того, чтобы у меня хотябы сбилдился проект, пришлось сделать поля статическими (что неправильно).
В общем случае неправильно.
В данном случае работает, потому что одновременно захват нескольких элементов не предусмотрен.
А если придётся перемещать несколько, то сразу будет попандос.

Вам нужно привязать какие-то значения к тому же объекту для которого создано AP-свойство.
Два основных варианта:
1) дополнительное приватное AP-свойство? которое буде хранить контейнер с нужными данными. В данном случае - это просто Point начальной позиции, но можно сделать какой-то приватный класс со множеством свойств. Он и будет играть роль тела Behavior:
2) В случае когда можно определить момент отписки/подписки (как в данной задаче), можно использовать статический словарь где элемент ключ, а значение это контейнер с данными.

Есть ещё третий вариант со словарём со слабыми ссылками - он используется когда момент удаления связи нельзя определить.
В данном случае это избыточно.
1
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
13.12.2021, 19:55  [ТС]
Чё-то мне кажется вы мудрите
Элд Хасп, да конечно мудрю, ещё и как.

Добавлено через 2 минуты
Зум здесь не должен играть роль.
Элд Хасп, я уже пробовал так — получается такой эффект: курсор действительно перемещает элемент, но чем дальше он меняет позицию — тем больше получается зазор между самим элементом и курсором мыши. При делении на фактор зума — работает без артифактов.

Добавлено через 2 минуты
Если у вас в Модели (SomeType) есть зум и нужно его учитывать при привязке к его свойствам Position, то это нужно делать в конвертере привязки.
А то получается у вас первичная привязка без зума, а смещение с зумом.
Действительно.

Добавлено через 5 минут
В общем случае неправильно.
В данном случае работает, потому что одновременно захват нескольких элементов не предусмотрен.
Я понимаю это, но мне интересно как это делается вообще. Ибо в обычное Property первым параметром всегда приходит сам объект, поэтому можно сделать что-то на подобие такого:
C#
1
2
var @this = (DragPosition)d;
var test = @this.pointId;
Но в данном случае приходит ContentPresenter. К такому меня жизнь не готовила ещё.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16152 / 11273 / 2890
Регистрация: 21.04.2018
Сообщений: 33,147
Записей в блоге: 2
13.12.2021, 19:58
Цитата Сообщение от limeniye Посмотреть сообщение
но мне интересно как это делается вообще.
Постараюсь завтра показать.
1
13.12.2021, 19:59  [ТС]

Не по теме:

Элд Хасп, очень онтересно.

0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16152 / 11273 / 2890
Регистрация: 21.04.2018
Сообщений: 33,147
Записей в блоге: 2
14.12.2021, 18:13
Цитата Сообщение от limeniye Посмотреть сообщение
очень онтересно
Буду делать в отдельной ветки eldhasp чтобы не путаться с вашими изменениями.

Иду по пути полной аналогии, а уже потом, при желании, можно будет вносить в него изменения.
Для начала удаляю ZoomFactor - на мой взгляд от него только путаница как при реализации, так и при использовании.
А из Parent - делаю AP-свойство.
Проверяем работу - всё ок!
Фиксация ab79449d.
0
14.12.2021, 18:29  [ТС]

Не по теме:

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Буду делать в отдельной ветки eldhasp чтобы не путаться с вашими изменениями.
Да, поддерживаю эту идею.

0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16152 / 11273 / 2890
Регистрация: 21.04.2018
Сообщений: 33,147
Записей в блоге: 2
14.12.2021, 18:42
limeniye, продолжаем.
Теперь можно безболезненно убрать наследование от DependencyObject.

Дальше определяем какие элементы нужны для обработчиков события и выносим их в отдельный класс.
В обработчиках у нас идёт обращение: к самому элементу, к родительской панели, точки относительно которой идёт перемещение.
Вроде, всё.
Сами обработчики тоже переносим в доп.класс:
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
using System;
using System.Diagnostics;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Input;
 
namespace DragPositionDemonstrateProject
{
    public partial class DragPositionBehavior
    {
        private class HandlersData
        {
            private Point prevPoint;
            private int pointerId = -1;
            int countMove;
 
            private readonly UIElement parent;
            private readonly UIElement element;
 
            public HandlersData(UIElement element, UIElement parent)
            {
                this.parent = parent ?? throw new ArgumentNullException(nameof(parent));
                this.element = element ?? throw new ArgumentNullException(nameof(element));
 
                element.AddHandler(UIElement.PointerPressedEvent, (PointerEventHandler)OnElementPointerPressed, true);
            }
 
            private void OnElementPointerPressed(object sender, PointerRoutedEventArgs e)
            {
                parent.AddHandler(UIElement.PointerReleasedEvent, (PointerEventHandler)OnElementPointerReleased, true);
 
                countMove = 0;
                parent.PointerMoved += OnMove;
 
                prevPoint = e.GetCurrentPoint(parent).Position;
                pointerId = (int)e.Pointer.PointerId;
            }
 
            private void OnElementPointerReleased(object sender, PointerRoutedEventArgs e)
            {
                parent.RemoveHandler(UIElement.PointerReleasedEvent, (PointerEventHandler)OnElementPointerReleased);
 
                parent.PointerMoved -= OnMove;
 
                if (e.Pointer.PointerId != pointerId)
                    return;
 
                pointerId = -1;
            }
 
            private void OnMove(object sender, PointerRoutedEventArgs e)
            {
                Debug.WriteLine($"{countMove++}: {sender}");
                double zommFactor = 1;
 
                var pos = e.GetCurrentPoint(null).Position;
 
                SetOffsetX(element, GetOffsetX(element) + (pos.X - prevPoint.X) / zommFactor);
                SetOffsetY(element, GetOffsetY(element) + (pos.Y - prevPoint.Y) / zommFactor);
 
                prevPoint = pos;
            }
 
 
        }
    }
}
Используем его в Attach:
C#
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
        public void Attach(DependencyObject associatedObject)
        {
            if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
            {
                return;
            }
 
            if (!(associatedObject is UIElement associatedUIElement))
            {
                throw new ArgumentException("Только для UIElement", nameof(associatedObject));
            }
 
            HandlersData handlersData = new HandlersData(associatedUIElement, GetBaseParent(associatedUIElement));
 
            //if (associatedObject != AssociatedObject)
            //{
            //    AssociatedObject = associatedObject;
            //    AssociatedUIElement = associatedUIElement;
 
            //    //associatedUIElement.PointerPressed += OnElementPointerPressed;
            //    associatedUIElement.AddHandler(UIElement.PointerPressedEvent, (PointerEventHandler)OnElementPointerPressed, true);
            //}
 
 
        }
Проверяем работу - всё Ок!
Фиксация 67bc3249.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16152 / 11273 / 2890
Регистрация: 21.04.2018
Сообщений: 33,147
Записей в блоге: 2
14.12.2021, 19:30
limeniye, продолжаем.

Теперь можно удалить все обработчики из Behavior.
Остаются только методы Attach и Detach.

В этих методах происходит отключение-подключение прослушки основного события и нужно сохранять экземпляр HandlersData.
Сделаем под него приватное AP-свойство.

И в его изменение будет делать действия из Attach и Detach.

Для начала в HandlersData добавляем возможность уничтожения экземпляра:
C#
12
13
14
15
16
17
18
19
20
21
22
        private class HandlersData : IDisposable
        {
            public void Dispose()
            {
                IsDispose = true;
                element.RemoveHandler(UIElement.PointerPressedEvent, (PointerEventHandler)OnElementPointerPressed);
                parent.RemoveHandler(UIElement.PointerReleasedEvent, (PointerEventHandler)OnElementPointerReleased);
                parent.PointerMoved -= OnMove;
            }
 
            public bool IsDispose { get; private set; }
Создаёт само AP-свойство:
C#
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
        /// <summary>Возвращает значение присоединённого свойства HandlersData для <paramref name="element"/>.</summary>
        /// <param name="element"><see cref="UIElement"/> значение свойства которого будет возвращено.</param>
        /// <returns><see cref="HandlersData"/> значение свойства.</returns>
        private static HandlersData GetHandlersData(UIElement element)
        {
            return (HandlersData)element.GetValue(HandlersDataProperty);
        }
 
        /// <summary>Задаёт значение присоединённого свойства HandlersData для <paramref name="element"/>.</summary>
        /// <param name="element"><see cref="UIElement"/> значение свойства которого будет возвращено.</param>
        /// <param name="value"><see cref="HandlersData"/> значение для свойства.</param>
        private static void SetHandlersData(UIElement element, HandlersData value)
        {
            element.SetValue(HandlersDataProperty, value);
        }
 
        /// <summary><see cref="DependencyProperty"/> для методов <see cref="GetHandlersData(UIElement)"/> и <see cref="SetHandlersData(UIElement, HandlersData)"/>.</summary>
        private static readonly DependencyProperty HandlersDataProperty =
            DependencyProperty.RegisterAttached(nameof(GetHandlersData).Substring(3), typeof(HandlersData), typeof(DragPositionBehavior),
                new PropertyMetadata(null, HandlersDataChanged));
 
        private static void HandlersDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UIElement element = (UIElement)d;
            if(e.OldValue is HandlersData handlersData)
            {
                handlersData.Dispose();
            }
        }
Тела Attach и Detach отключаем (закомментировал их).
Создание и сохранение HandlersData делаем в методе DragPositionChanged:
C#
55
56
57
            UIElement element = (UIElement)d;
            HandlersData handlersData = new HandlersData(element, GetBaseParent(element));
            SetHandlersData(element, handlersData);
Проверяем - всё Ок.
Фиксация f1160e67.

Добавлено через 14 минут
Теперь чистка кода, переименование.
Фиксация bfe8fa41.

Добавлено через 4 минуты
На этом рефакторинг закончен.

Но нужно ещё вынести в отдельный класс "обходной манёвр" что я сделал для возможности задания привязок в сеттерах.
Нужно его сделать обобщенным, что бы можно было использовать с любым классом.
Создавать его надо на основе стиля или на основе коллекции SetterBaseCollection.
Но можно и свою каку-то придумать, которая будет принимать сеттеры.

Сможете с этим справиться7
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.12.2021, 19:30
Помогаю со студенческими работами здесь

Вызвать событие при перемещении курсора
Здравствуйте всем! Вопрос: Среда разработки — Microsoft Visual Studio 2010 C# ASP.NET Web Form Проблема — при наведении мышью на...

Событие при при перемещении курсора мыши в уже выпавшем списке ComboBox
Всех с Наступившим Новым Годом! Счастья и удачи побольше в этом году! Не подскажите ли какое событие возникает при перемещении курсора...

Процессор нагружается при перемещении курсора мыши
Здравствуйте, проблему описал в заголовке. Не понимаю, что делать, почти всё перепробовал. Такое началось относительно недавно, точную дату...

Word: запускать макрос при перемещении курсора
Возможно ли, чтобы макрос запускался автоматически при изменении позиции курсора? То есть, например, я сейчас нахожусь в ячейке 1-го...

Использование tab при перемещении курсора по объектам
Добрый вечер! Столкнулся с такой проблемой, на форме создаю много объектов, если их создаешь в последовательности, то при нажатии TAB...


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

Или воспользуйтесь поиском по форуму:
56
Ответ Создать тему
Новые блоги и статьи
20. Мат мед. Абсентеизм как отдельный тип простоя
anaschu 29.05.2026
Апдейт модели: исправленные баги, абсентеизм и новые механизмы Продолжаю развивать ранее описанную модель рабочего коллектива на AnyLogic. За последние несколько дней был проведён серьёзный. . .
19. здоровье, усталость и психотип работника влияют на производительность предприятия, и наоборот, производительность на здоровье, усталось и психотип
anaschu 28.05.2026
Дискретно-событийная модель рабочего коллектива на AnyLogic: здоровье, выгорание, психотипы и микростимуляция Привет, коллеги. Хочу поделиться итогами нескольких недель работы над симуляционной. . .
"Прокси" для последовательного порта
Eddy_Em 28.05.2026
Эту штуку написал я достаточно давно. Но сейчас вот понадобилось настроить датчик грозы, но при этом не отключать его от "метеодемона". Соответственно, надо запустить этот "прокси": метеодемон будет. . .
Рефакторинг программы уравнивания.
Massaraksh7 26.05.2026
Пример по предыдущей записи в блоге. Но, надо заметить, что, во-первых, там оптимизация не только математики, но и работы с базой данных, и с графами, а во-вторых, это ещё не всё.
Использование TThread в Lazarus для математических вычислений.
Massaraksh7 25.05.2026
Производя рефакторинг своих программ на предмет ускорения их работы, обратил внимание на такой аспект, как сокращение времени матвычислений. Дело в том, что приходится работать с большими матрицами. . .
Модель здравосохранения 18. Чем здоровее работник, тем быстрее выгорает
anaschu 24.05.2026
Имитационная модель корпоративного здравоохранения: что показывает математика Сегодня в модели рабочего коллектива на AnyLogic появились три новые механики — выгорание через накопленную усталость,. . .
Модель здравосохранения 17. Планы на выгорание
anaschu 23.05.2026
Вот конкретная схема реализации: В классе Работник добавить: накопленнаяУсталость — растёт каждый час работы, снижается в перерывы и болезни коэффициентПрезентеизма — снижает продуктивность. . .
Изменение цветов в палитре gif файла aka фавикона
russiannick 23.05.2026
Изменение цветов в палитре gif файла, юзаемого как фавиконка в составе html-файла, помещенная в base64, средствами нативного Java Script, навеянное сном в майский день. Для работы необходим браузер,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru