namespace HistoryView.Controls { /// /// Interaction logic for WarningPopUp.xaml /// public partial class WarningPopUp : UserControl { public WarningPopUp() { InitializeComponent(); _timer = new(); _timer.Elapsed += new System.Timers.ElapsedEventHandler(TimerCallBack); _timer.Interval = 10000; _timer.AutoReset = false; _timer.Enabled = false; } private readonly System.Timers.Timer _timer; private void TimerCallBack(object? sender, System.Timers.ElapsedEventArgs e) { App.Current.Dispatcher.Invoke(() => { this.IsOpen = false; }); } private int Counter { get { return (int)GetValue(CounterProperty); } set { SetValue(CounterProperty, value); } } // Using a DependencyProperty as the backing store for Counter. This enables animation, styling, binding, etc... public static readonly DependencyProperty CounterProperty = DependencyProperty.Register("Counter", typeof(int), typeof(WarningPopUp), new PropertyMetadata(default)); internal ObservableDictionary> AlarmSource { get { return (ObservableDictionary>)GetValue(AlarmSourceProperty); } set { SetValue(AlarmSourceProperty, value); } } // Using a DependencyProperty as the backing store for AlarmSource. This enables animation, styling, binding, etc... public static readonly DependencyProperty AlarmSourceProperty = DependencyProperty.Register("AlarmSource", typeof(ObservableDictionary>), typeof(WarningPopUp), new PropertyMetadata(default, AlarmsPropertyChangedCallback)); private static WarningPopUp? _warning; static void AlarmsPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is not WarningPopUp warning) return; _warning = warning; if (e.NewValue is not ObservableDictionary> and || and is null) return; and.CollectionChanged += And_CollectionChanged; warning.Counter = and.Count; warning.WarningHint.Visibility = and.Count switch { 0 => Visibility.Collapsed, _ => Visibility.Visible, }; } private static void And_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (_warning is null) return; if (_warning.AlarmSource.Count == 0) { _warning.WarningHint.Visibility = Visibility.Collapsed; _warning.Counter = 0; //animationEvent.Reset(); _warning.PopPos.Background = new SolidColorBrush(Colors.Transparent); } else { _warning.WarningHint.Visibility = Visibility.Visible; //_warning.IsOpen = _warning.Counter < _warning.AlarmSource.Count; _warning.Counter = _warning.AlarmSource.Count; //if (!animationEvent.WaitOne(0)) //{ // animationEvent.Set(); // Task.Factory.StartNew(_warning.Animation); //} } } private readonly static ManualResetEvent animationEvent = new(false); private void Animation() { while (animationEvent.WaitOne(0)) { try { App.Current.Dispatcher.Invoke(() => { this.PopPos.Background = (Brush)App.Current.Resources["EmergencyColor"]; }); Thread.Sleep(1000); App.Current.Dispatcher.Invoke(() => { this.PopPos.Background = new SolidColorBrush(Colors.Transparent); }); Thread.Sleep(1000); } catch { } } } public ICommand ClCommand { get { return (ICommand)GetValue(ClCommandProperty); } set { SetValue(ClCommandProperty, value); } } // Using a DependencyProperty as the backing store for ClCommand. This enables animation, styling, binding, etc... public static readonly DependencyProperty ClCommandProperty = DependencyProperty.Register("ClCommand", typeof(ICommand), typeof(WarningPopUp), new PropertyMetadata(default)); private bool IsOpen { get { return (bool)GetValue(IsOpenProperty); } set { SetValue(IsOpenProperty, value); } } public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(WarningPopUp), new PropertyMetadata(false, PropertyChangedCallback)); private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is not WarningPopUp pop) return; if (e.NewValue is not bool b || b == false) return; pop._timer.Stop(); pop._timer.Start(); } private void Button_Click(object sender, RoutedEventArgs e) { this.IsOpen = false; this._timer.Stop(); } } }