Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/13: Рейтинг темы: голосов - 13, средняя оценка - 5.00
1181 / 623 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
1
WPF

TimeLine поля

07.08.2020, 07:18. Показов 2549. Ответов 56
Метки fps (Все метки)

Author24 — интернет-сервис помощи студентам
На просторах интернетов заметил интересную тему и решил её раскрутить, ибо показалась мне сложной .
Задача состоит в том, чтобы сделать аналог полей в видеоредакторах.
Почему эта тема сразу показалась мне сложной? — если до этого я работал с объектами и не более, то сейчас я даже не могу понять с чем мне работать.
1. Вверху должена быть 24 часовая полоса с делениями часового диапазона(Первый UC). И хорошо, если пользователь оставил свой видос вначале , но если он 5-ти секундный видос захочет переместить на 20 000 попугаев вправо(относительно лева), то тогда в оперативу загрузится 5 тысяч таких часовых полосок(UserControl'ов). Думаю кулер начнёт орать на всю комнату, что тебе пора выключать компутатор, или он позовёт своего соседа Экрана Синевицкого.
Следовательно, как я прикинул, в ходе должно участвовать, допустим, 3 таких UserControl'ов, которые будут меняться друг за другом создавая эдакую иллюзию множества.
2. Допустим, но тут у меня сразу появляется вопрос об взаимодействии с событием Scroll.
В интернетах я, в рамках своей неопытности видать, не нашёл много информации о ScrollBar'е. Я пытался при изменении его Value создать и подключить событие, которое будет менять значение положения примитивному прямоугольнику. Как я только не танцевал с бубном а всё равно ничего не получилось.

Подытожу: должно быть 2 UserControl'a — часовая шкала и сам прямоугольник, которые меняют своё положение и уходят за границы экрана в следствии передвижения ползунка ScrollBar'a. Они не просто должны уходить за рамки, а и перемещаться за рамки с противоположной стороны экрана и менять свой размер длины(продолжительности минут "видеоролика").

Информацию разместил на просторах GitHub:
http://github.com/limeniye/xsenio

Буду обновлять по мере каких-то результатов(которые будут, если меня подтолкнут).
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.08.2020, 07:18
Ответы с готовыми решениями:

Не понял как прикрутить timeline
Здесьнаходиться обзор классной timeline.Вот скачал я библиотеку, добавил в reference в...

Создать конструктор класса TimeLine с параметрами
Как создать конструктор класса TimeLine с параметрами, т.е. конструктор не по-умолчанию. То есть...

WPF Binding поля, в качестве поля - объекта класса
Есть вопрос, как можно выполнить биндинг поля объекта класса? Для примера есть такая конструкция:...

Невозможно выполнить выборку по имени поля (по номеру поля все работает)
Вот кусок кода: conn = new SqlCeConnection("Data Source = Database.sdf;"); ...

56
Модератор
Эксперт .NET
15464 / 10710 / 2786
Регистрация: 21.04.2018
Сообщений: 31,529
Записей в блоге: 2
07.08.2020, 07:19 2
limeniye, не знаю как остальные, но я совершенно не понял, что вы хотите реализовать.
Не говоря уже о том как это должно выглядеть.
0
1181 / 623 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
07.08.2020, 07:24  [ТС] 3
Выглядеть примерно так. Но при при перемещении ползунка ничего не произойдёт(ссылку обновил на гитхаб), а должно приперемещении ползунка вправо — эти ораньжевые прямоугольники смещаться влево.
Миниатюры
TimeLine поля  
0
Модератор
Эксперт .NET
15464 / 10710 / 2786
Регистрация: 21.04.2018
Сообщений: 31,529
Записей в блоге: 2
07.08.2020, 08:00 4
Цитата Сообщение от limeniye Посмотреть сообщение
Выглядеть примерно так.
Первое что в голову приходит - Обрабатывать события скрула.

В VM задать отображаемый диапазон: начало и конец.
И коллекция попадающих в этот диапазон элементов.
У каждого элемента свойства для привязки: ширина и цвет.
Расчёт коллекции должен происходить автоматически при изменении диапазона.

По события скрула - изменяются границы диапазона.

Можно ещё добавить масштабирование по которому будет изменять размер диапазона.

Добавлено через 5 минут
Можно ещё попробовать использовать ListBox с отключенным элементами (если не нужна возможность их выбора).
В ListBox встроена виртуализация, и он загружает только видимые элементы.
Но прокрутка в ListBox идёт поэлементная, а не плавная.

Возможно это можно настроить, надо посмотреть.
В том числе, надо попробовать отключить в ListBox встроенный скрул, а сам ListBox поместить целиком во внешний скрул.
0
1181 / 623 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
07.08.2020, 11:55  [ТС] 5
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Первое что в голову приходит - Обрабатывать события скрула.
В VM задать отображаемый диапазон: начало и конец.
И коллекция попадающих в этот диапазон элементов.
У каждого элемента свойства для привязки: ширина и цвет.
Расчёт коллекции должен происходить автоматически при изменении диапазона.
По события скрула - изменяются границы диапазона.
Можно ещё добавить масштабирование по которому будет изменять размер диапазона.
_______________________

Сейчас покажу как я уже пытался такое сделать.
Класс, на данный момент, выглядит вот так:
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
public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            MaxTime = 40;
            TimeLine first = new TimeLine();
            first.Duration = new TimeSpan(1, 0, 0);
            first.Events.Add(new TimeLineEvent() { Start = new TimeSpan(0, 15, 0), Duration = new TimeSpan(0, 20, 0) });
            first.Events.Add(new TimeLineEvent() { Start = new TimeSpan(0, 40, 0), Duration = new TimeSpan(0, 10, 0) });
            first.Events.Add(new TimeLineEvent() { Start = new TimeSpan(0, 0, 0), Duration = new TimeSpan(0, 6, 0) });
            this.TimeLines.Add(first);
 
            TimeLine second = new TimeLine();
            second.Duration = new TimeSpan(1, 0, 0);
            second.Events.Add(new TimeLineEvent() { Start = new TimeSpan(0, 0, 0), Duration = new TimeSpan(0, 5, 0) });
            second.Events.Add(new TimeLineEvent() { Start = new TimeSpan(0, 30, 0), Duration = new TimeSpan(0, 15, 0) });
            second.Events.Add(new TimeLineEvent() { Start = new TimeSpan(0, 50, 0), Duration = new TimeSpan(0, 10, 0) });
            this.TimeLines.Add(second);
        }
 
        private int _maxTime;
        public int MaxTime { get => _maxTime; set { Set(() => MaxTime, ref _maxTime, value); } }
 
        private int _scrollValue;
        public int ScrollValue { get => _scrollValue; set { Set(() => ScrollValue, ref _scrollValue, value); } }
 
        private ObservableCollection<TimeLine> _timeLines = new ObservableCollection<TimeLine>();
        public ObservableCollection<TimeLine> TimeLines { get =>_timeLines; set{ Set(() => TimeLines, ref _timeLines, value); } }
    }
C#
1
2
3
4
5
6
7
8
    public class TimeLineEvent : ObservableObject
    {
        private TimeSpan _start;
        public TimeSpan Start { get => _start; set { Set(() => Start, ref _start, value); } }
 
        private TimeSpan _duration;
        public TimeSpan Duration { get => _duration; set{ Set(() => Duration, ref _duration, value); } }
    }
C#
1
2
3
4
5
6
7
8
    public class TimeLine : ObservableObject
    {
        private TimeSpan _duration;
        public TimeSpan Duration { get =>_duration; set{ Set(() => Duration, ref _duration, value); } }
 
        private ObservableCollection<TimeLineEvent> _events = new ObservableCollection<TimeLineEvent>();
        public ObservableCollection<TimeLineEvent> Events { get =>_events; set { Set(() => Events, ref _events, value); } }
    }
Я пытался, для начала, сделать примерно так:
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
    private RelayCommand _scrolling;
    public ICommand Scrolling
    {
        get
        {
            return _scrolling ??
                (
                _scrolling = new RelayCommand
                    (
                        () =>
                        {
                            //тут могут быть ошибки, ибо пишу с телефона, но я пытался
                            //первому элементу в каждой строке изменять значения минут
                            //тут ещё конвертацию нужно делать, но для примера  так
                            //и прога начинала ругаться как только я дотрагивался до Scroll-ползунка
                            foreach(var line in TimeLines)
                            { 
                                line[0].Start = new TimeSpan(0, (int)ScrollTimer, 0);
                            }
                        },
                        () =>
                        {
                            return true;
                        }
                    )
                );
        }
    }
И в событие я пытался подключить так:
XML
1
<ScrollBar Scroll="Scrolling" Value="{Binding ScrollValue}" Orientation="Horizontal" Minimum="0" Maximum="{Binding MaxTime}"/>
Я сомневаюсь что я всё правильно делаю в этом моменте: Scroll="Scrolling"
_______
0
Модератор
Эксперт .NET
15464 / 10710 / 2786
Регистрация: 21.04.2018
Сообщений: 31,529
Записей в блоге: 2
07.08.2020, 13:34 6
limeniye, по пользованию редактором:
 Комментарий модератора 
При обращении к другому пользователю указывайте его ник в тегах [NICK][/NICK] или цитируйте часть сообщения на которое отвечаете.
В противном случае ему не придёт уведомление о вашем обращении и вы можете не дождаться ответа на своё сообщение.

Для вставки ника: введите ник, выделите его и нажмите кнопку "Динамик" на панели редактора сообщений.
Или кликните по нику автора сообщения в панели слева от текста его сообщения.

Для вставки цитаты: выделите нужную цитату, должна появиться всплывающая кнопка "Цитировать", нажмите её.


Добавлено через 7 минут
Цитата Сообщение от limeniye Посмотреть сообщение
Я сомневаюсь что я всё правильно делаю в этом моменте: Scroll="Scrolling"
Если Scrolling - это свойство-команда реализация которого показана выше, то должна быть привязка ...="{Binding Scrolling}".
НО!
Что это за свойство такое ScrollBar.Scroll ?
У ScrollBar, вроде, нет такого свойства.
0
1181 / 623 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
07.08.2020, 13:58  [ТС] 7
Цитата Сообщение от Элд Хасп Посмотреть сообщение
У ScrollBar, вроде, нет такого свойства.
мне высвечивает такое свойство само, но что это такое я не понимаю. В интернете искал — не нашёл. Методом ТЫКА и логики именований решил, что это свойство скроллинга у него.
0
Модератор
Эксперт .NET
15464 / 10710 / 2786
Регистрация: 21.04.2018
Сообщений: 31,529
Записей в блоге: 2
07.08.2020, 14:02 8
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Что это за свойство такое ScrollBar.Scroll ?
Блин!
Это же событие!
К нему нельзя задать привязку, но передать делегат обработчика.
Связь с VM - неоднозначна.

Добавлено через 2 минуты
limeniye, тут надо не просто общие советы, а сидеть кодить.
Не сказать что сложно, но кода будет много.

Первая (верхняя) полоска что у вас отображает?
Цитата Сообщение от limeniye Посмотреть сообщение
Вверху должена быть 24 часовая полоса с делениями часового диапазона
Это яно не то что вы написали.
0
1181 / 623 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
07.08.2020, 18:28  [ТС] 9
Элд Хасп, Ох, так на столько всё ужасно?
Я думал там пару строк для связки с ScrollBar и дальше я бы пытался сделать что-то типо:
"если прямоугольник вышел за рамки видимого диапазона, тогда он может взять свойства (начальной точки и конечной точки) следующего прямоугольника".
Этот пример взят из просторов интернета.
______________________________________________

Я попробую реализовать это +- так, как Вы показывали(просьба не закидывать меня помидорами).

1. Как полоса часового диапазона (нет, она не сделана, потом сделаю, пока не важно), так и прямоугольные примитивы имеют схожие действия: они должны менять своё положение в зависимости от того, если они не в зоне видимости(а точней, они должны телепортироваться), а также они должны перемещаться в рамках видимости(но просто перемещаться, а не телепортироваться, на рисунке будет показано о чём я говорю).

Для этого буду отслеживать Visible элемент, или Unvisible.

В примере ниже я также создал ещё такое событие как "ЧастичнаяВидимость".
Данное событие лишнее и только уменьшает скорость, но я хотел бы чтобы оно всё же пока побыло.
Дело в том, что для примитивной демонстрации я хочу в TextBlock, в итоге, выводить состояние первого элемента: "Элемент пропал из зоны видимости в левую сторону", "Элемент пропал из зоны видимости в праву сторону", "Элемент частично за рамками видимости", "Элемент виден".

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
  public class ElementDto
  {
    ///<summary>Начальная точка элемента</summary>
    public double FirstPoint {get;set;}
        
    ///<summary>Конечная точка элемента</summary>      
    public double EndPoint {get;set;}
 
    ///<summary>Конструктор элемента<summary>
    ///<param name = "firstPoint">Точка начала элемента</param>
    ///<param name = "endPoint">Точка конца элемента</param>
    public ElementDto(double firstPoint, double endPoint)
    {this.FirstPoint = firstPoint; this.EndPoint = endPoint;}
  }
 
  public enum ActionStatusVisibilityEnum
  {
    ///<summary>Элемент в видимом диапазоне</summary>
    Visible,
    ///<summary>Элемент в невидимом диапазоне слева</summary>
    Unvisible_LeftSide,
    ///<summary>Элемент в невидимом диапазоне справа</summary>
    Unvisible_RightSide,
    ///<summary>Элемент виден частично</summary>
    PartialVisibility
  }
 
  public delegate void ActionStatusVisibilityHandler<T>(object sender, ActionStatusVisibilityEnum action, T item);
 
  public partial class ElementChangingModel
  {
    public event ActionStatusVisibilityHandler<ElementDto> ActionElements;
 
    private void RaiseActionElements(ActionStatusVisibilityEnum action, ElementDto element)
            => ActionElements?.Invoke(this, action, element);
  }
 
 
//Теперь нужно расписать логику взаимодействия элементов друг с другом.
 
  public partial class ElementChangingModel
  {
    ///<summary>Размер видимого пользователем диапазона</summary>
    public double WidthArea {get;}
    
    
    ///<summary>Проверка на статус видимости</summary>
    ///<param name="element">Dto-объект элемента</param>
    public void ElementChekerVisibility(ElementDto element)
    {
      
      if(element.FirstPoint<0 && element.EndPoint<0) 
        RaiseActionElements(ActionStatusVisibilityEnum.Unvisible_LeftSide, element);
      else if(element.FirstPoint>WidthArea && element.EndPoint>WidthArea)
        RaiseActionElements(ActionStatusVisibilityEnum.Unvisible_RightSide, element);
      else if((element.FirstPoint > 0) && (element.EndPoint < WidthArea))
        RaiseActionElements(ActionStatusVisibilityEnum.Visible, element);
      else if(((element.FirstPoint<0) && ((element.EndPoint<WidthArea) && (element.EndPoint>0)))
      ||
      ((element.FirstPoint>0) && (element.FirstPoint<WidthArea)) && (element.EndPoint>WidthArea))
        RaiseActionElements(ActionStatusVisibilityEnum.PartialVisibility, element);
      else
        throw new ArgumentException("Не найден статус видимости элемента. Нужно перепроверить код");
    }
    
    
    ///<summary> Расстояние между невидимым элементом и рамкой видимого диапазона</summary>
    ///<param name = "element">Dto-объект элемента</param>
    public double DistansFromElementToVisibleBox(ElementDto element)
    {
      //вот идея, но как реализовать не понимаю(
      //if(enum == Unvisible_RightSide)
      //..return element.FirstPoint - WidthArea;
      //else if(enum == Unvisible_LeftSide)
      //..return element.EndPoint*(-1);
      return 0;
    }
    
  }
Хотел бы обратить внимание на последний метод DistansFromElementToVisibleBox , возвращающий какое-то расстояние и хотел бы поговорить о нём подробнее.
И так мой криворукий и "наглядный" скрин:

TimeLine поля


За рамками видимости будет 1 прямоугольник, который будет находиться либо слева за рамкой, либо справа.
Он будет телепортироваться с стороны на сторону в зависимости от того, какая точка будет ближе, чтобы когда подвести ScrollBar'ои эту точку ещё ближе к зоне видимости, прямоугольник был уже готов заранее. То есть это типо предугадывание поведения пользователя и подготовка элемента ДО появления.
Подытожу: две точки за рамками видимости и какая точка ближе к зоне видимости, свойства той точки и будет принимать прямоугольник.
0
Модератор
Эксперт .NET
15464 / 10710 / 2786
Регистрация: 21.04.2018
Сообщений: 31,529
Записей в блоге: 2
07.08.2020, 18:43 10
Цитата Сообщение от limeniye Посмотреть сообщение
Ох, так на столько всё ужасно?
Не ужасно, а просто много кода, хоть и не сказать что он будет сложный.

Давайте для начала определимся с самой задачей.

Вернёмся к рисунку из третьего поста:

1) Что это за две линии вверху? Между ними есть связь или нет?

2) Цвет каждого сегмента имеет какое-то заданное значение или это просто любые два цвета поочерёдно применяемые к сегментам?

3) Доп к п.2. Если поочерёдно, то как определяется чья очередь? Какой цвет первый? С учётом того, что это только часть условно бесконечной линии.

4) Так как мы работаем с диапазонами, то можно ли все исходные данные представить как отсортированную последовательность double ?

5) Будет ли масштабирование? Изменение выводимого промежутка?

Добавлено через 3 минуты
6) Какие требования к точности и диапазону исходных данных? Надо выбрать их тип. double самый простой в работе (для данной задачи), но у него могут быть проблемы с точностью при очень больших диапазонах.
Поэтому, может быть стоить выбрать один из: int, long или decimal.
Если знак не нужен, то ещё можно и uint или ulong.
0
1181 / 623 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
07.08.2020, 19:05  [ТС] 11
Элд Хасп,

1. Две эти линии это
C#
1
2
TimeLine first = new TimeLine();
TimeLine second = new TimeLine();
и на каждой линии есть прямоугольники:
C#
1
2
//Это первый зелёный прямоугольник
first.Events.Add(new TimeLineEvent() { Start = new TimeSpan(0, 15, 0), Duration = new TimeSpan(0, 20, 0) });
2. Это серая линия, а не ней зелёные прямоугольники созданные в конструкторе.
3. Очередь, в первом примере, определяется начальной точкой и конечной каждого элемента, которые имеют не координаты, а (часы,минуты,секунды).
4. Ммм, не совсем понимаю вопрос. Оно должно вообще генерировать какой-то диапазон, например 20 000 элементов с разными начальными и конечными точками в диапазоне от минуты до 10, например. И когда ScrollBar перемещается — перебираются элементы из какого-то массива. Тогда да, он должен быть отсортирован: то если ползунок ScrollBar'a находится по середине, то и в массиве пользователь должен быть посередине .
5. Каждый массив можно сгенерировать по новой и,например, двигать элементы не нужно. Но вы писали о том, что можно сделать через ListBox, но тогда нельзя будет возможность перемещать элементы, а я бы хотел всё-таки посмотреть, как бы это выглядело без него с перемещением.
6. Вообще я хотел через double, чтобы был более точный просчёт.

Добавлено через 3 минуты
Также хотел бы уточнить, что генерируются "якобы" 20 000 прямоугольников, а на самом то деле их 5, просто они перемещаются и делают иллюзию что каждый раз это новый прямоугольник.
0
Модератор
Эксперт .NET
15464 / 10710 / 2786
Регистрация: 21.04.2018
Сообщений: 31,529
Записей в блоге: 2
07.08.2020, 20:14 12
Цитата Сообщение от limeniye Посмотреть сообщение
1. Две эти линии это
Насколько понял, это две независимые коллекции, но с одинаковым отображаемым диапазоном.

Цитата Сообщение от limeniye Посмотреть сообщение
2. Это серая линия, а не ней зелёные прямоугольники созданные в конструкторе.
Это понял.
Значит у нас есть для каждого сегмента: начало и его длина.
Могут ли сегменты накладываться?
Если не могут, но придут такие данные, что делать? Отобразить как пришли, или проверять на ошибку и выдавать исключение?

Цитата Сообщение от limeniye Посмотреть сообщение
3. Очередь, в первом примере, определяется начальной точкой и конечной каждого элемента, которые имеют не координаты, а (часы,минуты,секунды).
Это не правильно.
В общем виде - это числовая задача.
А исходные данные (допустим, время) надо предварительно приводить к числам.
Для TimeSpan - это Total...

Цитата Сообщение от limeniye Посмотреть сообщение
4. Ммм, не совсем понимаю вопрос.
Это я не правильно понял.
Сейчас изменяю вопрос.
У нас есть две коллекции.
В каждой коллекции элементы со свойствами: начало и длина.
Обе коллекции отсортированы по свойству "начало".

Цитата Сообщение от limeniye Посмотреть сообщение
5. Каждый массив можно сгенерировать по новой и,например, двигать элементы не нужно.....
Я здесь вижу такую реализацию.
Есть входные коллекции.
Есть выходные коллекции для привязки.
Задавая диапазон - мы проецируем исходные коллекции на коллекции для отображения.

В исходных коллекциях начало задаётся в абсолютных единицах, в коллекция для отображения - относительно начала отображаемого диапазона.

Масштабирование.
У нас есть какие-то условные единицы.
Эти условные единицы совершенно не связаны с экранными единицами.
А для UI элементов нужны экранные единицы.

Допустим, мы считаем в минутах и у нас диапазон - один час, то есть 60 минут.
Но выводим мы на ширину 1100.
Следовательно нужно масштабирование от 60 к 1100.

Это можно делать средствами WPF.
Используется ViewBox.
Но при больших коэффициентах масштаба могут проявиться баги разрешения.

Можно это делать программно, но тогда появляется задача передачи значения ширины (UI диапазона) в наш класс для его обработки.
Работать будет лучше, но добавится кода как при реализации так и при использовании.

Цитата Сообщение от limeniye Посмотреть сообщение
6. Вообще я хотел через double, чтобы был более точный просчёт.
Здесь у вас пробел в знаниях основ C#.
Double - неточный тип. У него самый большой ДИАПАЗОН значений, но точность его ограничена 52 двоичными знаками.
У ulong - 64 двоичных разряда.
У decimal - 96 двоичных разрядов.

Если исходные данные поступают из TimeSpan, то свойства Total... возвращают double.
Поэтому лучше, на мой взгляд, на нём и остановиться.

Цитата Сообщение от limeniye Посмотреть сообщение
Также хотел бы уточнить, что генерируются "якобы" 20 000 прямоугольников, а на самом то деле их 5, просто они перемещаются и делают иллюзию что каждый раз это новый прямоугольник.
Угу.
Это я понял.
Будет некий абстрактный метод запрашивающий данные для указанного диапазона, и метод будет возвращать коллекцию элементов "начало и длина".
0
1181 / 623 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
07.08.2020, 23:02  [ТС] 13
Элд Хасп,
Цитата Сообщение от Элд Хасп
Могут ли сегменты накладываться?
— Я думал об этом и пришёл к выводу что если элемент находится под элементом, то его оттенок меняется в какой-то заданной формуле. Если будет много слоёв под слоями — получится градиент.

_______________________________________________________________

По поводу сортировки массива. Просто я представлял не так всё и массив не нужно было бы сортировать.
Но поразмыслив часа пол, мне кажется что это всё таки будет разумнее и проще.

_______________________________________________________________

Цитата Сообщение от Элд Хасп
Можно это делать программно, но тогда появляется задача передачи значения ширины (UI диапазона) в наш класс для его обработки
Речь идёт о диапазоне видимых единиц пользователю?
У меня есть такая строка
C#
1
public double WidthArea {get;}
надеюсь Вы о ней говорите.

_______________________________________________________________

Цитата Сообщение от Элд Хасп
Будет некий абстрактный метод запрашивающий данные для указанного диапазона, и метод будет возвращать коллекцию элементов "начало и длина".
Хм, думаю для меня это будет сложно:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  public class ElementDto
  {
    
    ///<summary>Начальная точка элемента</summary>
    public double FirstPoint {get;set;}
        
    ///<summary>Конечная точка элемента</summary>      
    public double EndPoint {get;set;}
 
    ///<summary>Конструктор элемента<summary>
    ///<param name = "firstPoint">Точка начала элемента</param>
    ///<param name = "endPoint">Точка конца элемента</param>
    public ElementDto(double firstPoint, double endPoint)
    {
      this.FirstPoint = firstPoint; 
      this.EndPoint = endPoint;
    }
    
  }
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
  public enum ActionStatusVisibilityEnum
  {
    ///<summary>Элемент в видимом диапазоне</summary>
    Visible,
    ///<summary>Элемент в невидимом диапазоне слева</summary>
    Unvisible_LeftSide,
    ///<summary>Элемент в невидимом диапазоне справа</summary>
    Unvisible_RightSide,
    ///<summary>Элемент виден частично</summary>
    PartialVisibility
  }
 
  public delegate void ActionStatusVisibilityHandler<T>(object sender, ActionStatusVisibilityEnum action, T item);
 
  public partial abstract class OutLogic
  {
    public event ActionStatusVisibilityHandler<ElementDto> ActionElements;
 
    private void RaiseActionElements(ActionStatusVisibilityEnum action, ElementDto element)
            => ActionElements?.Invoke(this, action, element);
  }
 
 
  
  public partial abstract class OutLogic
  {
    
    ///<summary>Размер видимого пользователем диапазона</summary>
    public double WidthArea {get;set;}
    
    
    ///<summary>Проверка на статус видимости</summary>
    ///<param name="element">Dto-объект элемента</param>
    public void ElementChekerVisibility(ElementDto element)
    {
      
      if(element.FirstPoint<0 && element.EndPoint<0) 
        RaiseActionElements(ActionStatusVisibilityEnum.Unvisible_LeftSide, element);
      else if(element.FirstPoint>WidthArea && element.EndPoint>WidthArea)
        RaiseActionElements(ActionStatusVisibilityEnum.Unvisible_RightSide, element);
      else if((element.FirstPoint > 0) && (element.EndPoint < WidthArea))
        RaiseActionElements(ActionStatusVisibilityEnum.Visible, element);
      else if(((element.FirstPoint<0) && ((element.EndPoint<WidthArea) && (element.EndPoint>0)))
      ||
      ((element.FirstPoint>0) && (element.FirstPoint<WidthArea)) && (element.EndPoint>WidthArea))
        RaiseActionElements(ActionStatusVisibilityEnum.PartialVisibility, element);
      else
        throw new ArgumentException("Не найден статус видимости элемента. Нужно перепроверить код");
    }
    
    ///<summary>Логика отображения колекций<summary>
    public abstract void ShowSigmentLogic();
    
  }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  public class TimeLine:OutLogic
  {
    
    ///<summary>Четыре часовые шкалы по 12 часов одна за другой</summary>
    public ObservableCollection<ElementDto> TimeLineList { get; }
            = new ObservableCollection<ElementDto>()
                {
                    new ElementDto(1,12),
                    new ElementDto(12,24),
                    new ElementDto(24,36),
                    new ElementDto(36,48)
                };
    
    public override void ShowSigmentLogic()
    {
            
    }  
    
  }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  public class Rectangle:OutLogic
  {
    
    ///<summary> Расстояние между невидимым элементом и рамкой видимого риапазона Рис.1</summary>
    ///<param name = "element">Dto-объект элемента</param>
    public double DistansFromElementToVisibleBox(ElementDto element)
    {
      //if(enum == Unvisible_RightSide)
      //..return element.FirstPoint - WidthArea;
      //else if(enum == Unvisible_LeftSide)
      //..return element.EndPoint*(-1);
      return 0;
    }
    
    public override void ShowSigmentLogic()
    {
      
    }
  }
сложно, но я что-то да написал.
0
Модератор
Эксперт .NET
15464 / 10710 / 2786
Регистрация: 21.04.2018
Сообщений: 31,529
Записей в блоге: 2
08.08.2020, 09:23 14
limeniye, вы до сих пор с телефона отвечаете?
А как собираетесь кодить?
0
1181 / 623 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
08.08.2020, 12:33  [ТС] 15
Я просто не дома, а компилирую и дорабатываю всё ночью у друга на ноуте через Team Viewer, пока он спит.
Компа нет(в данный момент), а задание всё равно хочу понять, ибо оно для меня тяжёлое и поняв его, мой скилл апнется.
Компа нет, а прогрессировать хочется, поэтому вручную ставлю каждые пробелы табуляции )

Добавлено через 5 минут
Это конечно очень долго и сложнее, но это лучше чем сидеть дома в Коронавирус и ничем не заниматься как Амёба, или Инфузория Туфелька

Добавлено через 1 минуту
Элд Хасп, Забыл Вас ответить
0
Модератор
Эксперт .NET
15464 / 10710 / 2786
Регистрация: 21.04.2018
Сообщений: 31,529
Записей в блоге: 2
08.08.2020, 13:10 16
Цитата Сообщение от limeniye Посмотреть сообщение
Я просто не дома, а компилирую и дорабатываю всё ночью у друга на ноуте через Team Viewer, пока он спит...

УЖАС!!!
Сочувствую.
А в аренду не найти?
Хоть простенький?
Вам же для Студии любой подойдёт.
Киньте клич по соцсетям, наверняка у кого-то, дома неиспользуемое старьё валяется, пылится.
Может и откликнется кто-нибудь.
0
Модератор
Эксперт .NET
15464 / 10710 / 2786
Регистрация: 21.04.2018
Сообщений: 31,529
Записей в блоге: 2
08.08.2020, 15:02 17
Теперь по коду.
1) DTO - это:
Data Transfer Object (DTO) — один из шаблонов проектирования, используется для передачи данных между подсистемами приложения. Data Transfer Object, в отличие от business object или data access object не должен содержать какого-либо поведения.
В большинстве случаев, DTO тип иммутабельный.
То есть у него все свойства "Только Для Чтения".
Ваш тип ElementDto явно не соответствует этому определению.
Поэтому назовём его StripSegment.

Так же его свойства предназначены джля привязки в WPF View, поэтому сделаем производным от: Новая реализация OnPropertyChangedClass [WPF, Элд Хасп]

2) Какие свойства нужны у этого типа?
Начало и Конец - это ясно.
Но нам в View потребуется ещё и задать ширину элементам представляющим Сегмент.
Поэтому нужна ещё Длина.

Так же нужно автоматическое вычисление значений зависимых свойств.

Пример реализации:
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
using Common;
 
namespace StripSegments
{
    /// <summary>Класс Сегмента Полосы.</summary>
    public class StripSegment : OnPropertyChangedClass
    {
        #region Поля, хранящие значения одноимённых свойств
        private double _begin;
        private double _end;
        private double _length;
        #endregion
 
        /// <summary>Начало Сегмента.</summary>
        public double Begin { get => _begin; set => SetProperty(ref _begin, value); }
        /// <summary>Конец Сегмента.</summary>
        public double End { get => _end; set => SetProperty(ref _end, value); }
        /// <summary>Длина Сегмента.</summary>
        public double Length { get => _length; set => SetProperty(ref _length, value); }
 
        protected override void PropertyNewValue<T>(ref T fieldProperty, T newValue, string propertyName)
        {
            base.PropertyNewValue(ref fieldProperty, newValue, propertyName);
 
            // Пересчёт значений свойств при изменении одного их них.
            switch (propertyName)
            {
                // Если изменяется Начапло или Конец, то пересчитывается Длина.
                case nameof(End):
                case nameof(Begin):
                    Length = Begin - End;
                    break;
 
                // Если изменяется длина, то пересчитывается Конец.
                case nameof(Length):
                    End = Begin + Length;
                    break;
 
                default:
                    break;
            }
        }
    }
}
Архив с Решение приложен.
В нём есть проект Common.
Я его перекинул из другого Решения. В нём типы которые могут пригодиться, чтобы не делать их реализацию каждый раз заново.
Вложения
Тип файла: 7z StripSegmentsSln(limeniye-0808).7z (11.9 Кб, 1 просмотров)
0
Модератор
Эксперт .NET
15464 / 10710 / 2786
Регистрация: 21.04.2018
Сообщений: 31,529
Записей в блоге: 2
08.08.2020, 15:14 18
Дальше нам нужен тип получающий на вход коллекцию исходных данных.

Вот здесь у меня нет понимания.

Это может быть отсортированная коллекция StripSegmentsDto (только два иммутабельных свойства Начало и Конец).
Тогда нужно автоматически отслеживать изменения этой коллекции. И откуда она приходит?

Или метод получающий в параметрах StripSegmentsDto задающий диапазон отображения и возвращающий отсортированную коллекцию StripSegmentsDto.

Как вы это видите?
0
1181 / 623 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
08.08.2020, 15:16  [ТС] 19
Элд Хасп, я тут переписал всё, через минут 20 кину. Посмотрите?
0
Модератор
Эксперт .NET
15464 / 10710 / 2786
Регистрация: 21.04.2018
Сообщений: 31,529
Записей в блоге: 2
08.08.2020, 15:20 20
Цитата Сообщение от limeniye Посмотреть сообщение
public enum ActionStatusVisibilityEnum
По-моему, это излишне.
Для чего свойство с этим типом?

Если использовать его для элементов коллекции предназначенной для отображения - есть всё равно риск перегрузки GUI.
Слишком большая коллекция.

Лучше сделать фильтрацию элементов из исходной коллекции в коллекцию предназначенную для отображения.
В отфильтрованной коллекции будет очень мало элементов, и ни какого риска перегрузки GUI.

Добавлено через 21 секунду
Цитата Сообщение от limeniye Посмотреть сообщение
Посмотрите?
Конечно.
0
08.08.2020, 15:20
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.08.2020, 15:20
Помогаю со студенческими работами здесь

Передача поля в контроллер из вьюшки без пападания поля во вьюшку
Здравствуйте. Имеется контроллер: public class TestController { public long...

Заполнение базы данных с определенного номера поля ключевого поля
Добрый день, написан код для заполнения таблицы на c#, но при запуске выдает ошибку, что не может...

как сделать Поля таблицы на русском и скрыть поля счетчик в windows forms
как правильно сделать Поля таблицы на русском и скрыть поля счетчик в windows forms? SQL server...

При достижении края поля объект должен перерисовываться с противоположной стороны поля
Доброе время суток коллеги. Перейду сразу к делу, имеется игровое поле на котором нанесены объекты,...

Данные в combobox одного поля, заменить значением другого поля при сохранении в файл базы
Здравствуйте! суть вопроса - беру данные из файла базы ssldb, таблица sites, поле site отображаю...

Описать класс студент, имеющий три поля предметов и 3 целочисленных поля – баллы, набранные по этим предметам
Здравствуйте! Хотел бы узнать правильно ли описаны классы и немного непонятно, про три поля...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru