Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 24.02.2022
Сообщений: 71

Открытие окна по таймеру WPF MVVM

06.12.2022, 08:36. Показов 1874. Ответов 26
Метки c#, mvvm, wpf (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, форумчане, знатоки WPV, MVVM! Снова прошу помощи)
Работаю над проектом, что-то вроде будильника(напоминания). По истечению времени, указанного пользователем, должно открываться небольшое окно с напоминаниями.
У меня есть основное окно, где в DataGrid отображаются сохраненные напоминания.
Есть окно, которое должно быть "всплывающим" при срабатывании таймера, и в которое должны передаваться данные из объекта, сохраненного в коллекции. И есть команда открытия "всплывающего окна".
На данный момент "всплывающее окно" привязано к кнопке в меню MainWindow. А вот как открыть это окно по истечении времени (не нажимая на кнопку) не представляю. Для таймера пока что есть только метод, который возвращает время в минутах.
Подскажите, возможно ли и как можно реализовать такую задачу?

Код главного окна:
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
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
<Window x:Class="Memory_Refresher.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Memory_Refresher"
        xmlns:cmd="clr-namespace:Memory_Refresher.Commands"
        xmlns:vm="clr-namespace:Memory_Refresher.ViewModels"
        xmlns:serv="clr-namespace:Memory_Refresher.Services"
        Title="{Binding Tittle}" MinHeight="500" MinWidth="800" Height="800" Width="1200"
        WindowStartupLocation="CenterScreen" Icon="/Views/Windows/MemoryRefresher.png">
    <Window.DataContext>
        <vm:MainWindow_VM/>
    </Window.DataContext>
    <Window.InputBindings>
        <KeyBinding Command="{Binding SaveRemindersCmd}" Key="S" Modifiers="Ctrl"/>
    </Window.InputBindings>
    <DockPanel>
        <StackPanel DockPanel.Dock="Top">
            <TextBlock FontSize="45"
                       Text="Memory Refresher++"
                       TextWrapping="Wrap" 
                       TextAlignment="Left"
                       VerticalAlignment="Center"
                       FontFamily="Algerian"
                       FontWeight="Normal" FontStyle="Normal">
                <TextBlock.Foreground>
                    <LinearGradientBrush>
                        <GradientStop Color="GreenYellow" Offset="0.1"/>
                        <GradientStop Color="Yellow"  Offset="0.2"/>
                        <GradientStop Color="Red" Offset="1"/>
                    </LinearGradientBrush>
                </TextBlock.Foreground>
                <TextBlock.Background>
                    <LinearGradientBrush  StartPoint="0,0" EndPoint="1,9">
                        <GradientStop Color="LimeGreen" Offset="0.85"/>
                        <GradientStop Color="Blue" Offset="0.75"/>
                        <GradientStop Color="Red" Offset="0.65"/>
                        <GradientStop Color="Yellow" Offset="0.5"/>
                        <GradientStop Color="Black" Offset="0.4"/>
                    </LinearGradientBrush>
                </TextBlock.Background>
            </TextBlock>
        </StackPanel>
        <Menu DockPanel.Dock="Top"
              Style="{StaticResource MenuCustomStyle}">
            <MenuItem Header="Файл">
                <MenuItem Header="Новое напоминание"
                          Style="{StaticResource MenuItemStyle}">
                    <MenuItem.Command>
                        <cmd:AddNewReminderCommand/>
                    </MenuItem.Command>
                </MenuItem>
                <MenuItem Header="Сохранить все напоминания   Ctrl+S"
                          Style="{StaticResource MenuItemStyle}"
                          Command="{Binding SaveRemindersCmd}"/>
 
                <MenuItem Header="Сохранить и выйти"
                          Style="{StaticResource MenuItemStyle}"
                          Command="{Binding CloseApp}"/>
            </MenuItem>
            <MenuItem Header="Помощь"
                      Style="{StaticResource MenuItemStyle}"/>
            <MenuItem Header="Окно будильника"                      
                      Style="{StaticResource MenuItemStyle}">
                <MenuItem.Command>
                    <cmd:OpenAlarmWindowCommand/>
                </MenuItem.Command>
            </MenuItem>
        </Menu>
 
        <TabControl DockPanel.Dock="Bottom"
                    Style="{StaticResource TabControlStyle}">            
            <TabItem Header="Напоминания" FontSize="14"
                     Style="{StaticResource TabItemCustomStyle}">
                <DockPanel>
                    <StackPanel x:Name="Buttons"
                                DockPanel.Dock="Top"
                                VerticalAlignment="Top"
                                Orientation="Horizontal"
                                Height="40">
                        <Button Content="Новое напоминание"
                                Width="200"
                                Margin="5"
                                Height="30"                    
                                HorizontalAlignment="Left"
                                Style="{StaticResource CheckButtonStyle}">
                            <Button.Command>
                                <cmd:AddNewReminderCommand/>
                            </Button.Command>
                        </Button>
                        
                        <Button Content="Сохранить"
                                Width="200"
                                Margin="5"
                                Height="30" 
                                HorizontalAlignment="Left"
                                Style="{StaticResource SaveButtonStyle}"
                                Command="{Binding SaveRemindersCmd}">
                        </Button>
 
                        <Button Content="Удалить напоминание"
                                Width="200"
                                Margin="5"
                                Height="30" 
                                HorizontalAlignment="Left"
                                Style="{StaticResource RemoveButtonStyle}"
                                Command="{Binding ReminderDeleteCmd}">
                        </Button>
                        <StackPanel.Background>
                            <LinearGradientBrush >
                                <GradientStop Color="#FFEAEAEA" Offset="1.5"/>
                                <GradientStop Color="#FFBDF3F3" Offset="1.3"/>
                                <GradientStop Color="#FFC9EDED" Offset="1"/>
                                <GradientStop Color="#FFD5EFFF" Offset="0.5"/>
                            </LinearGradientBrush>
                        </StackPanel.Background>
                    </StackPanel>
                    <DataGrid AutoGenerateColumns="False"
                              CanUserAddRows="False"
                              CanUserDeleteRows="False"
                              CanUserReorderColumns="False"
                              IsReadOnly="True"
                              Background="LightGray"
                              ItemsSource ="{Binding Source={x:Static serv:Collections.Reminders}}"
                              SelectedItem="{Binding SelectedReminder}">
                        <DataGrid.InputBindings>
                            <KeyBinding Key="Delete" Command="{Binding ReminderDeleteCmd}"/>
                        </DataGrid.InputBindings>
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="Index"
                                                Width="75"
                                                Binding="{Binding IndexReminder}"/>
                            <DataGridTextColumn Header="Заголовок" 
                                                Width="250"
                                                Binding="{Binding TittleReminder}"/>
                            <DataGridTextColumn Header="Текст"
                                                Width="*"
                                                Binding="{Binding MessageReminder}">
                                <DataGridTextColumn.ElementStyle>
                                    <Style TargetType="TextBlock">
                                        <Setter Property="TextWrapping" Value="Wrap"/>
                                    </Style>
                                </DataGridTextColumn.ElementStyle>
                            </DataGridTextColumn>
                            <DataGridTextColumn Header="Время напоминания"
                                                Width="200"
                                                Binding="{Binding DateTimeReminder, StringFormat={}{0:HH:mm}}" />
                            <DataGridTextColumn Header="Дата напоминания"
                                                Width="200"
                                                Binding="{Binding DateTimeReminder, StringFormat={}{0:dd.MM.yyyy}}"/>
                        </DataGrid.Columns>
                        <DataGrid.ContextMenu>
                            <ContextMenu>
                                <MenuItem Header="Выполнено"
                                          Command="{Binding ReminderCompletedCmd}"/>
                                <MenuItem Header="Удалить напоминание"
                                          Command="{Binding ReminderDeleteCmd}"/>
                            </ContextMenu>
                        </DataGrid.ContextMenu>
                    </DataGrid>
                </DockPanel>
            </TabItem>
            <TabItem Header="База знаний" FontSize="14"
                     Style="{StaticResource TabItemCustomStyle}">                
            </TabItem>
        </TabControl>
    </DockPanel>
 
</Window>
Код "всплывающего окна"

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<Window x:Class="Memory_Refresher.Views.Windows.AlarmWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Memory_Refresher.Views.Windows"
        Title="AlarmWindow" Height="250" Width="450"
        WindowStartupLocation="Manual">
    <DockPanel Background="#FFE6FFFB">
        <StackPanel DockPanel.Dock="Top">
            <TextBlock FontSize="20"
                       Text="Внимание!"
                       TextWrapping="Wrap" 
                       TextAlignment="Center"
                       VerticalAlignment="Center"
                       FontFamily="Monotype Corsiva"
                       FontWeight="Bold"
                       FontStyle="Normal"                       
                       Foreground="#FF5A00FF">
                <TextBlock.Background>
                    <LinearGradientBrush>
                        <GradientStop Color="#ff3f00" Offset = "0.2"/>
                        <GradientStop Color="#ff7200" Offset="0.3"/>
                        <GradientStop Color="#ff7200" Offset="0.4"/>
                        <GradientStop Color="#ffd800" Offset="0.5"/>
                        <GradientStop Color="#ff7200" Offset="0.6"/>
                        <GradientStop Color="#ff7200" Offset="0.7"/>
                        <GradientStop Color="#ff3f00" Offset="0.8"/>
                    </LinearGradientBrush>
                </TextBlock.Background>
            </TextBlock>
        </StackPanel>
        <StackPanel DockPanel.Dock="Top">
            <TextBlock FontSize="20"
                       Text="Сработало напоминание!"
                       TextWrapping="Wrap" 
                       TextAlignment="Center"
                       VerticalAlignment="Center"
                       FontFamily="Monotype Corsiva"
                       FontWeight="Bold"
                       FontStyle="Normal"                       
                       Foreground="#FF5A00FF"
                       Margin="0,-1,0,-1">
                <TextBlock.Background>
                    <LinearGradientBrush>
                        <GradientStop Color="#ff3f00" Offset = "0.2"/>
                        <GradientStop Color="#ff7200" Offset="0.3"/>
                        <GradientStop Color="#ff7200" Offset="0.4"/>
                        <GradientStop Color="#ffd800" Offset="0.5"/>
                        <GradientStop Color="#ff7200" Offset="0.6"/>
                        <GradientStop Color="#ff7200" Offset="0.7"/>
                        <GradientStop Color="#ff3f00" Offset="0.8"/>
                    </LinearGradientBrush>
                </TextBlock.Background>
            </TextBlock>
        </StackPanel>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="0.7*"/>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="0.4*"/>
            </Grid.RowDefinitions>
            <TextBox Grid.Row="0"
                       Margin="5"
                     IsReadOnly="True"
                     BorderThickness="0.5"
                     BorderBrush="#FF0D1BF3"/>
            <TextBox Grid.Row="1"
                       Margin="5"
                     IsReadOnly="True"
                     BorderThickness="0.5"
                     BorderBrush="#FF0D1BF3"/>
            <Button Grid.Row="2"
                    Content="Отложить"
                    VerticalAlignment="Center"
                    HorizontalAlignment="Left"
                    FontSize="12"
                    Height="24"
                    Margin="5,5,5,5"
                    Padding="5,0,5,0"
                    Style="{StaticResource RemoveButtonStyle}"/>
            <Button Grid.Row="2"
                    Content="Выключить"
                    VerticalAlignment="Center"
                    HorizontalAlignment="Right"
                    FontSize="12"
                    Height="24"
                    Margin="5"
                    Padding="5,0,5,0"
                    Background="Green"
                    Style="{StaticResource CheckButtonStyle}"/>
        </Grid>
    </DockPanel>
 
</Window>
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
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
internal class MainWindow_VM : Base_VM, IDownloadReminders
    {
        #region заголовок окна
        private string _Tittle = "Memory Refresher++";
        /// <summary>Заголовок окна </summary>
        public string Tittle
        {
            get => _Tittle;
            set => Set(ref _Tittle, value);
        }
        #endregion
 
        #region Свойства, привязанные к онку
        public Reminder SelectedReminder { get; set; }
 
        #endregion
 
        #region Команды
 
        #region Сохранение в файл
        //Команда сохранения в файл
 
        public ICommand SaveRemindersCmd { get; }
        private bool CanSaveRemindersCmdExecute(object p) => true;
        private void OnSaveRemindersCmdExecuted(object p)
        {
            ISaveReminders(Collections.Reminders);
        }
        #endregion //Сохранение в файл
 
        #region Команда на статус "Напомнинание выполнено"
        public ICommand ReminderCompletedCmd { get; }
        private bool CanReminderCompletedCmdExecute(object p) => true;
        private void OnReminderCompletedCmdExecuted(object p)
        {
            IReminderCompleted(SelectedReminder, Collections.Reminders);
        }
 
        #endregion //Команда на статус "Напомнинание выполнено"
 
        #region Удаление напоминания из файла
        public ICommand ReminderDeleteCmd { get; }
        private bool CanReminderDeleteCmdExecute(object p) => true;
        private void OnReminderDeleteCmdExecuted(object p)
        {
            IReminderDelete(SelectedReminder, Collections.Reminders);
        }
 
        #endregion
 
        #region Команда сохранения и закрытия приложения
        public ICommand CloseApp { get; }
        private bool CanCloseAppExecute(object p) => true;
        private void OnCloseAppExecuted(object p)
        {
            ISaveReminders(Collections.Reminders);
            System.Windows.Application.Current.Shutdown();
        }
 
        #endregion
 
        #endregion //команды
 
        #region Конструктор
        public MainWindow_VM()
        {
            //new Thread(() => IDownloadReminders(Collections.Reminders)).Start();
            IDownloadReminders(Collections.Reminders);
            NextReminderTime(Collections.Reminders);
            CloseApp = new LamdaCommand(OnCloseAppExecuted, CanCloseAppExecute);
            ReminderDeleteCmd = new LamdaCommand(OnReminderDeleteCmdExecuted, CanReminderDeleteCmdExecute);
            SaveRemindersCmd = new LamdaCommand(OnSaveRemindersCmdExecuted, CanSaveRemindersCmdExecute);
            ReminderCompletedCmd = new LamdaCommand(OnReminderCompletedCmdExecuted, CanReminderCompletedCmdExecute);
        }
 
        #endregion
 
        #region методы
        //метод возвращает интервал времени в минутах для ближайшего напоминания (используется для таймера)
        private double NextReminderTime(ObservableCollection<Reminder> Reminders)
        {
            double x = 0;
 
            if (Reminders.Count != 0)
            {
                Reminder rem = Reminders[0];
                TimeSpan interval = (DateTime.Now - rem.DateTimeReminder).Duration();
 
                x = interval.TotalMinutes;
            }
            
 
            
            return x;
        }
 
 
        #endregion
 
        #region Реализация интерфейса IDownloadReminders
 
        //сохранение в файл
        public void ISaveReminders(ObservableCollection<Reminder> collections)
        {
            var exePath = AppDomain.CurrentDomain.BaseDirectory;
            var path = Path.Combine(exePath + @"\..\..\Data\Reminders\");
 
            var options = new JsonSerializerOptions
            {
                WriteIndented = true
            };
            string json = JsonSerializer.Serialize(collections, options);
            File.WriteAllText(path + @"reminders.json", json);
        }
        //загрузка из файла
        public void IDownloadReminders(ObservableCollection<Reminder> collection)
        {
            string exePath = AppDomain.CurrentDomain.BaseDirectory;
            string path = Path.Combine(exePath + @"\..\..\Data\Reminders\");
 
            string jsonString = File.ReadAllText(path + @"reminders.json");
            try
            {
                var remiders = JsonSerializer.Deserialize<ObservableCollection<Reminder>>(jsonString);
 
                foreach (Reminder reminder in remiders)
                {
                    Reminder rem1 = new Reminder();
                    if(reminder.statusReminder == false)
                    {
                        rem1 = reminder;
                    }
                    else { break; }
                    
                    collection.Add(rem1);
                }
            }
 
            catch
            {
                return;
            }
        }
 
        //присваивание напоминанию статуса выполнено и исключение из коллекции
 
        public void IReminderCompleted(Reminder SelectReminder, ObservableCollection<Reminder> collection)
        {
            SelectedReminder.statusReminder = true;
            collection.Remove(SelectReminder);
        }
 
        //удаление напоминания
 
        public void IReminderDelete(Reminder SelectReminder, ObservableCollection<Reminder> collection)
        {
            collection.Remove(SelectReminder);
            //ISaveReminders(collection);
        }
    }
Класс "Базовой команды"
C#
1
2
3
4
5
6
7
8
9
10
11
12
internal abstract class BaseCommand : ICommand
    {
        public event EventHandler CanExecuteChanged
        {
            add => CommandManager.RequerySuggested += value;
            remove => CommandManager.RequerySuggested -= value;
        }
 
        public abstract bool CanExecute(object parameter);
 
        public abstract void Execute(object parameter);
    }
Команда открытия "Всплывающего окна". На данный момент привязана к кнопке в MainWindow
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
internal class OpenAlarmWindowCommand : BaseCommand
    {
        double workHeight = SystemParameters.FullPrimaryScreenHeight;
        double workWidth = SystemParameters.FullPrimaryScreenWidth;
 
        private AlarmWindow _Window;
        public override bool CanExecute(object parameter) => _Window == null;
        public override void Execute(object parameter)
        {
 
            AlarmWindow window = new AlarmWindow();
            _Window = window;
 
            window.Top = workHeight-220;
            window.Left = workWidth-450;
            window.Owner = Application.Current.MainWindow;
            window.Closed += OnWindowClosed;
            window.Show();
        }
 
        private void OnWindowClosed(object Sender, EventArgs E)
        {
            ((Window)Sender).Closed -= OnWindowClosed;
            _Window = null;
        }
    }
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.12.2022, 08:36
Ответы с готовыми решениями:

WPF MVVM отключить/включить кнопку по таймеру
private DelegateCommand _selectDirCommand; public ICommand SelectDirCommand { get { ...

WPF MVVM Закрытие/Открытие окон
Доброго времени суток. Там не новая, но нуждаюсь в том, чтобы ткнули носом. Исходные данные: Есть главное окно программы, которое...

Открытие окна, MVVM
Доброго времени суток, форумчане. Столкнулся с проблемкой небольшой. Необходимо в нужный момент открыть новое окно с...

26
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
08.12.2022, 11:45
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Nickolass Посмотреть сообщение
Т.е. будет 3 проекта в одном: проект для модели(библиотека классов), интерфейсы и типы и основной проект?
Да. Потом ещё добавится проект для ViewModel.
В данном случае, это нужно для обучения. Чтобы вы поняли границы слоёв и ответственности.
0
0 / 0 / 0
Регистрация: 24.02.2022
Сообщений: 71
30.01.2023, 19:02  [ТС]
Элд Хасп, доброго времени суток!) Вроде наконец-то немного разобрался с событиями. Но вот пока не доходит как в этом примере создать событие для Timer.Tick, чтобы открывалось окно при срабатывании напоминания.

Пробовал создавать делегат и событие, при котором будет вызываться метод открытия окна. Какой бы код не писал, на строчке
C#
1
timer.Tick += //любой метод
появляется ошибка:
Ошибка CS0029 Не удается неявно преобразовать тип "void" в "System.EventHandler".
Весь код который писал сам стер уже, сохранил только ваш.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
RemindersChanged?.Invoke(this, new RemindersEventArgs(RemindersAction.Add, reminder));

Подскажите, плиз, куда копать? Какой метод должен быть подписан на событие Tick?
Во всех примерах, которые встречал, обрабатывается метод с параметрами (object sender, object e) для label в окне.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
30.01.2023, 20:14
Цитата Сообщение от Nickolass Посмотреть сообщение
Какой метод должен быть подписан на событие Tick?
Какой тимер используете?
Есть несколько разных тимеров и у каждого своя сигнатура события.

Добавлено через 2 минуты
Nickolass, постарайтесь залить Решение на GitHub (лучше через меню Git Студии) и дайте ссылку на него.
Так намного проще и быстрее будет разобраться.
0
0 / 0 / 0
Регистрация: 24.02.2022
Сообщений: 71
31.01.2023, 04:19  [ТС]
Элд Хасп, DispatcherTimer взял.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
31.01.2023, 09:59
Цитата Сообщение от Nickolass Посмотреть сообщение
DispatcherTimer взял.
Класс DispatcherTimer
Событие DispatcherTimer.Tick
Тип события

EventHandler
Определение

Пространство имен: System
Сборка: mscorlib.dll

Представляет метод, обрабатывающий событие, не имеющее данных.
C#
1
2
3
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public delegate void EventHandler(object sender, EventArgs e);
Обработчик должен иметь такую же сигнатуру как делегат события. То есть void SomeMethod(object sender, EventArgs e).

Добавлено через 3 минуты
Nickolass, DispatcherTimer стоит использовать ТОЛЬКО в слое WPF View. Это один из типов WPF. Его нельзя использовать на других платформах. Поэтому в слоях Model и ViewModel его использование нарушает MVVM.
0
0 / 0 / 0
Регистрация: 24.02.2022
Сообщений: 71
31.01.2023, 11:38  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
DispatcherTimer стоит использовать ТОЛЬКО в слое WPF View.
Элд Хасп, подскажите, какой тогда лучше взять, чтобы не нарушать MVVM? Читал, что есть 6 видов таймеров.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
31.01.2023, 14:01
Цитата Сообщение от Nickolass Посмотреть сообщение
какой тогда лучше взять, чтобы не нарушать MVVM?
Где вы его собираетесь применять?
Если в Модели, то обычно используют System.Timers.Timer или System.Threading.Timer.
Иногда удобно запускать вечный цикл в асинхронном методе. Пример: private static async void ChangeProduct().
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
31.01.2023, 14:01

WPF MVVM Закрытие окна
Добрый день. Очень давно ищу решение такой задачи, как закрытие формы при нажатии на кнопку... Часто, при поиске, читая комментарии над...

Открытие нового окна mvvm
Новое окно вызываю таким образом Link Link = new Link(); Link.Show(); Как в таком случае...

[WPF] Координаты окна в рамках MVVM
В WPF у окна есть несколько свойств, отвечающие за его расположение на экране: Left, Top. Как в рамках MVVM изменять эти свойства,...

WPF, MVVM, Переход из одного окна в другое
Здравствуйте. Пишу курсовой проект &quot;Электронный менеджер&quot;. И застопорился в самом начале. Подразумевается, что моим приложением будут...

WPF. MVVM. Как привязать команду к событию окна?
Когда окно запускается нужно сразу же выполнить команду, чтобы изменить свойство. Триггеры возможно. Не понимаю.


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

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
Новые блоги и статьи
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
День 5 из 28: Codex подсказывает следующий запрос
and_y87 12.10.2026
9 октября 2026 года OpenAI запустила бету Composer predictions — подсказок следующего сообщения в текущем диалоге Codex. Это помощь с формулировкой запроса, а не автоматическое продолжение задачи. . . .
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru