Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.64/39: Рейтинг темы: голосов - 39, средняя оценка - 4.64
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376

Рисую линию без MVVM все ОК. C MVVM произвольный старт

30.10.2021, 12:59. Показов 9686. Ответов 148
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день всем.

Рисую линию при помощи анимации. Все получилось -рисуется, стирается.
Но у нас все задания с MVVM, чтобы ViewModel была
Хорошо добавил MVVM light, ViewModel создал, свойства, команду.

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

Как такое может быть, если никто и ничто не воздействует на свойство и должно быть false?
Или она сама по себе запускается. Так вся разница между двумя проектами - МVVM.

Xaml.

XML
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
  <Window.Resources>
        <Storyboard x:Key="Storyboard.Draw2" x:Name="BeginStoryboardDraw2">
            <DoubleAnimation
                Storyboard.TargetProperty="X2"
                From="0"
                To="282"
                Duration="0:0:5" />
            <DoubleAnimation
                Storyboard.TargetProperty="Y2"
                From="0"
                To="11"
                Duration="0:0:5" />
        </Storyboard>
 
        <Storyboard x:Key="Storyboard.Erase2" x:Name="BeginStoryboardErase2">
            <DoubleAnimation
                Storyboard.TargetProperty="X1"
                From="0"
                To="282"
                Duration="0:0:5" />
            <DoubleAnimation
                Storyboard.TargetProperty="Y1"
                From="0"
                To="11"
                Duration="0:0:5" />
        </Storyboard>
    </Window.Resources>
 
    <Grid>
        <Canvas>
 
            <Line
                Name="MyLine3"
                Canvas.Left="100"
                Canvas.Top="100"
                Stroke="LimeGreen"
                StrokeThickness="6">
               
                <Line.Style>
                    <Style>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Animation_enable}" Value="true">
                                <DataTrigger.EnterActions>
                                    <BeginStoryboard x:Name="BeginStoryboardDraw2" Storyboard="{StaticResource Storyboard.Draw2}" />
                                </DataTrigger.EnterActions>
                                <DataTrigger.ExitActions>
                                   
                                </DataTrigger.ExitActions>
                            </DataTrigger>
 
                            <DataTrigger Binding="{Binding Animation_enable}" Value="false">
                                <DataTrigger.EnterActions>
                                    <BeginStoryboard x:Name="BeginStoryboardErase2" Storyboard="{StaticResource Storyboard.Erase2}" />
                                </DataTrigger.EnterActions>
                                <DataTrigger.ExitActions>
                                    <StopStoryboard BeginStoryboardName="BeginStoryboardErase2" />
                                </DataTrigger.ExitActions>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Line.Style>
            </Line>
 
        </Canvas>
 
        <Button
            Width="60"
            Height="20"
            Command="{Binding Launch_animation_command}"
            Content="Рисовать" />
 
</Grid>


VieModel

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
 // Animation enable
 
        public bool Animation_enable
        {
            get { return _animation_enable; }
            set { Set(ref _animation_enable, value); }
        }
        private bool _animation_enable;
 
 
 
        // Command
        public ICommand Launch_animation_command { get; private set; }
 
 
        public MainWindowViewModel()
        {
 
            Launch_animation_command = new RelayCommand(LaunchAnimation);
 
 
        }
 
 
 
        // Method
        private void LaunchAnimation()
        {
 
 
            if (!Animation_enable)
            {
 
                Animation_enable = true;
 
            }
 
            else if (Animation_enable)
 
            {
 
 
               Animation_enable = false;
 
            }
 
 
 
        }
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.10.2021, 12:59
Ответы с готовыми решениями:

Доступ к View без нарушения правил MVVM
Здравствуйте, дорогие форумчане. Я недавно начал изучать MVVM. Вот недавно столкнулся с одной проблемой: как мне , допустим, создать...

Привязка данных без использования паттерна MVVM
Здраствуйте, интересует вопрос как сделать такую привязку. Имеется класс Game.cs: class Game: DependencyObject { ...

MVVM
Здравствуйте, я в среде WPF нахожусь очень мало, посмотрел книжки, решил читать Мэтью Макдональда, стоит ли мне сразу изучать MVVM или...

148
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
01.11.2021, 20:39
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Berendom Посмотреть сообщение
Можно вопросы задавать?
Конечно.
Форум для этого и создан.
0
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
01.11.2021, 20:52  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
В данном случает реализована совместная Model+VM.
1) т.е. в принципе все эти свойства

C#
1
2
3
4
5
6
7
8
        private double _begin;
        private double _length;
        private DateTime _startTime;
 
        public double Begin { get => _begin; set => Set(ref _begin, value); }
        public double Length { get => _length; set => Set(ref _length, value); }
 
        public DateTime StartTime { get => _startTime; set => Set(ref _startTime, value); }

можно было закинуть в класс VM, а не отдельный класс Portion находящийся физически в той же VM.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
01.11.2021, 21:14
Цитата Сообщение от Berendom Посмотреть сообщение
можно было закинуть в класс VM, а не отдельный класс Portion находящийся физически в той же VM.
НЕТ!
Нам же в VM нужна коллекция порций (public ObservableCollection<Portion> Portions { get; }), а не один экземпляр.

Добавлено через 2 минуты
И он не находится "в той же VM".
Он находится на том же уровне.
А при полной реализации, он будет даже не проекте VM, а в библиотеке VM - там же где будет и интерфейс VM, кторый в данном случае не создаётся из-за упрощения реализации.
0
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
01.11.2021, 21:18  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
НЕТ!
Нам же в VM нужна коллекция порций (public ObservableCollection<Portion> Portions { get; }), а не один экземпляр.
а ObservableCollection нужен класс модели.

А я могу сделать так: отдельную папку Model, закинуть туда Portion?


2)

C#
1
2
3
4
5
6
7
8
9
 
        private double _begin;
        private double _length;
        private DateTime _startTime;
 
        public double Begin { get => _begin; set => Set(ref _begin, value); }
        public double Length { get => _length; set => Set(ref _length, value); }
 
        public DateTime StartTime { get => _startTime; set => Set(ref _startTime, value); }
есть какое-то преимущество вот такого написания свойств. private все в одной куче, остальное ниже.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
01.11.2021, 21:28
Цитата Сообщение от Berendom Посмотреть сообщение
а ObservableCollection нужен класс модели.
Тут ещё путаница в терминологии.
При работе с БД (ADO, EF и др.) моделями принято называть сущности отражающие данные БД.

А в ООП паттернах ПРИЛОЖЕНИЙ (MVC, MVP, MVVM и др.) Модель - это слой содержащий Бизнес Логику, в том числе и Репозиторий работающий с БД.

Поэтому, раз мы говорим о реализации MVVM, то ObservableCollection нужно типизировать какой-то сущностью.
Это сущность должна отражать отдельную порцию.
Для этого и был создан класс Portion.

Цитата Сообщение от Berendom Посмотреть сообщение
есть какое-то преимущество вот такого написания свойств. private все в одной куче, остальное ниже.
Дизайн, удобство чтения.
Мне так привычнее, удобнее.
Когда свойств очень много, все они сопровождаются тегами XML документации, то поля среди них мешают мне для восприятия кода.

Добавлено через 3 минуты
Цитата Сообщение от Berendom Посмотреть сообщение
А я могу сделать так: отдельную папку Model, закинуть туда Portion?
Нет.
Если выделять Модель в отдельный слой, то для "общения" с ним нужно создавать DTO типы.
Portion - имеет реализацию INPC, поэтому он не является DTO типом. Это сущность уровня VM.
0
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
01.11.2021, 21:38  [ТС]
3) не знал, что так буквально можно свойствам значения задавать.

XML
1
2
3
 <Window.DataContext>
        <vm:MainWindowViewModel ConveyorLength="800" Speed="50" />
    </Window.DataContext>
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
01.11.2021, 21:44
Цитата Сообщение от Berendom Посмотреть сообщение
3) не знал, что так буквально можно свойствам значения задавать.
Ну, как бы это основа XAML.
Новый тег - это вызов безпараметрического конструктора типа.
Атрибут - задание значения его свойству.

Добавлено через 3 минуты
Вот если потребуется обеспечить "резиновость", то есть чтобы размеры элементов динамически менялись при изменении размеров Окна, то придётся немного помудрить:
- или использовать ViewBox для автомасштабирования;
- или использовать Proxy или Behavior для передачи значений только для чтения из Окна в VM.
0
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
01.11.2021, 21:49  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Ну, как бы это основа XAML.
обычно в самом свойстве в VM пишем:

C#
1
2
3
4
5
 
   private double _speed = 50;
 
 
   public double Speed { get => _speed; set => Set(ref _speed, value); }
если в вашем стиле.



4)

C#
1
 timer = new Timer(OnTimer, null, 10, 10);
10ms тик, 10 ms пауза. Верно?
Какую роль таймер играет?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
01.11.2021, 23:16
Цитата Сообщение от Berendom Посмотреть сообщение
обычно в самом свойстве в VM пишем:
Так не очень хорошо делать.
Лучше присваивать начальные значения свойствам (отличные от дефолтным) в конструкторе класса, тогда гарантируется, что логика свойства правильно отработает.

Цитата Сообщение от Berendom Посмотреть сообщение
10ms тик, 10 ms пауза. Верно?
Верно.
Паузу можно и ноль поставить.
Я просто привык ставить одинаковые, поэтому сделал так "на автомате".

Цитата Сообщение от Berendom Посмотреть сообщение
Какую роль таймер играет?
Именно его событие двигает материалы по ленте.
Если это текущий материал, то увеличивается его длина.
Иначе - увеличивается начальное смещение.
Посмотрите логику метода private void OnTimer(object state).
0
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
02.11.2021, 08:54  [ТС]
5)

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
         <ToggleButton
                Margin="10"
                Padding="15,5"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                DockPanel.Dock="Left"
                IsChecked="{Binding IsMaterialsReceiving}">
                <ToggleButton.Style>
                    <Style TargetType="ToggleButton">
                        <Setter Property="Content" Value="Материал Cтарт" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding IsMaterialsReceiving}" Value="True">
                                <Setter Property="Content" Value="Материал Стоп" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ToggleButton.Style>
            </ToggleButton>

Тут для меня просто Америка открыта. До этого момента считал, что IsСhecked это обратная связь для управления самой toogglebutton, а не для изменения свойства в VM.
Я правильно понимаю здесь togglebutton воздействует на свойство IsMaterialReceiving?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
02.11.2021, 13:50
Цитата Сообщение от Berendom Посмотреть сообщение
Я правильно понимаю здесь togglebutton воздействует на свойство IsMaterialReceiving?
Да.
0
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
02.11.2021, 20:13  [ТС]
Элд Хасп, добрый вечер,

потестировал... и вспомнил! Нужно еще свойство, скажем, MaterialIsUnloading меняющееся с false на true когда материал или его кусок достигает крайней правой точки конвейера и соответственно меняется на false, когда заканчивается.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
02.11.2021, 20:49
Цитата Сообщение от Berendom Посмотреть сообщение
Нужно еще свойство, скажем, MaterialIsUnloading меняющееся с false на true когда материал или его кусок достигает крайней правой точки конвейера и соответственно меняется на false, когда заканчивается.
Попробуйте сами его добавить.
В методе OnTimer - после цикла проверяете первую порцию.
Если она в диапазоне конца конвейера - значит true,
0
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
02.11.2021, 21:12  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Попробуйте сами его добавить.
я не смогу, там логика - жесть.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
02.11.2021, 21:28
Лучший ответ Сообщение было отмечено Berendom как решение

Решение

Цитата Сообщение от Berendom Посмотреть сообщение
я не смогу, там логика - жесть.
ууу.... как всё запущено.
Какая жесть?
Там всего пара строк:
C#
81
82
83
84
85
86
87
88
89
                    }
                    remove.ForEach(portion => Portions.Remove(portion));
 
                    IsMaterialAtEnd = Portions.Any(portion => portion.Begin + portion.Length >= ConveyorLength);
                }
            }
        }
 
        public bool IsMaterialAtEnd { get => _isMaterialAtEnd; set => Set(ref _isMaterialAtEnd, value); }
XML
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
            <Canvas Width="905"
                    Height="106">
                <Ellipse Width="20" Height="20"
                         Canvas.Right="0"
                         Canvas.Top="-30">
                    <Ellipse.Style>
                        <Style TargetType="Ellipse">
                            <Setter Property="Fill" Value="Red"/>
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding IsMaterialAtEnd}"
                                             Value="True">
                                    <Setter Property="Fill" Value="Green"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Ellipse.Style>
                </Ellipse>
Исходники в Фиксации f62f676e:
Индикатор отсутсвия материала на конце конвейера.
2
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
02.11.2021, 21:44  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
ууу.... как всё запущено.
да запущено... Я ума не приложу как это все рисует линию, а вы мне

Цитата Сообщение от Элд Хасп Посмотреть сообщение
В методе OnTimer - после цикла проверяете первую порцию.
Если она в диапазоне конца конвейера - значит true,
0
28 / 16 / 2
Регистрация: 09.05.2020
Сообщений: 149
02.11.2021, 22:48
Элд Хасп,

Здрасте!

Berendom привет!

что-то с синтаксисом парюсь.

XML
1
2
3
4
5
6
7
8
9
10
11
12
         <DataTemplate x:Key="Portion.Template" DataType="{x:Type vm:Portion}">
            <Line
                Stroke="Orange"
                StrokeThickness="10"
                X2="{Binding Length}" />
        </DataTemplate>
        <Style x:Key="Portion.Style" TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding Begin}" />
        </Style>
        <ItemsPanelTemplate x:Key="Portions.Canvas">
            <Canvas />
        </ItemsPanelTemplate>
где,


XML
1
DataType="{x:Type vm:Portion}"
а если у меня нет vm:

и datacontext вот так?



XML
1
2
3
        <Window.DataContext>
        <Binding Path="_MainWindowViewModel" Source="{StaticResource locator}" />
        </Window.DataContext>
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
02.11.2021, 23:15
Цитата Сообщение от Berendom Посмотреть сообщение
Я ума не приложу как это все рисует линию, а вы мне
Я же объяснял.
Вам по заданию надо нарисовать представление порций материалов на конвейере.
Представлением такой коллекции будет пунктирная линия.
Для пунктирной линии надо задать начало каждого штриха и его длину.
Чтобы сделать это ещё и динамичным, надо добавить штамп времени.
В результате получаем простой тип с тремя свойствами.
Их длиной и положением управляем в событии таймера.
Одной кнопкой создаём новый штрих.
Второй - включаем отключаем выполнение метода таймера.

Добавлено через 1 минуту
Цитата Сообщение от Nguen Посмотреть сообщение
а если у меня нет vm:
и datacontext вот так?
Как это нет?
А что находится в свойстве locator._MainWindowViewModel?

Добавлено через 2 минуты
locator._MainWindowViewModel?
Цитата Сообщение от Nguen Посмотреть сообщение
DataType="{x:Type vm:Portion}"
vm - это префикс пространства имён.
Задайте тот в котором у вас находится класс Portion.
0
28 / 16 / 2
Регистрация: 09.05.2020
Сообщений: 149
02.11.2021, 23:25
Цитата Сообщение от Элд Хасп Посмотреть сообщение
vm - это префикс пространства имён.
Задайте тот в котором у вас находится класс Portion.
это понятно,
но у меня нет vm: префикса, так как datacontext сделан так.

XML
1
2
3
4
 
        <Window.DataContext>
        <Binding Path="_MainWindowViewModel" Source="{StaticResource locator}" />
        </Window.DataContext>
мне что префикс vm: специально для класса Portion создавать? Отдельно?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
02.11.2021, 23:31
Цитата Сообщение от Nguen Посмотреть сообщение
мне что префикс vm: специально для класса Portion создавать? Отдельно?
Как я могу сказать не знаю в каком пространстве вы его объявили?
Если в том же, что и Окно, то значит вместо vm используйте local.

Добавлено через 1 минуту
Задайте в ресурсах окна <Portion/> без префикса.
Студия сама подскажет какой нужно использовать префикс.

Добавлено через 44 секунды
Потому из ресурсов удалите эту строку, а префикс используйте в DataTemplate.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.11.2021, 23:31

Mvvm
Форумчане помогите разобраться есть простенькая модель public partial class Category:ViewModelBase { private int...

MVVM
Добрый день! Пытаюсь написать программу в стиле MVVM. Вопрос такой: как передать SelectedItem TreeView из xaml с помощью Binding в...

MVVM
Объясните пожалуйста следующие строки 1)Представление является подписчиком на событие изменения значений свойств или команд,...

x:Name в MVVM
Добрый день, как обращаться к объектам из VM по их x:Name? Например, у меня есть канвас в который я докидываю картинки по нажатию...

MVVM: модель?
Что это вообще такое в рамках реализации тонкого клиента? Полное текущее состояние клиентского приложения? Серверная часть не...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru