aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.Core/ExtendedObject.cs
blob: 63a75480cb8b5748bd34478ca830751f7b90ce12 (plain)
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
using LiteDB;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using Tango.Core.Commands;
using Tango.Core.IO;
using Tango.Logging;

namespace Tango.Core
{
    /// <summary>
    /// Represents an extension to the standard core object with support for property and relay commands changed event.
    /// </summary>
    /// <seealso cref="System.ComponentModel.INotifyPropertyChanged" />
    [Serializable]
    public class ExtendedObject : INotifyPropertyChanged
    {
        /// <summary>
        /// Occurs when after InvalidateRelayCommands is called.
        /// </summary>
        [field: NonSerialized]
        public event EventHandler RelayCommandsInvalidated;

        /// <summary>
        /// Gets the default log manager.
        /// </summary>
        [JsonIgnore]
        [NotMapped]
        [BsonIgnore]
        public LogManager LogManager
        {
            get { return LogManager.Default; }
        }

        /// <summary>
        /// Gets the temporary manager.
        /// </summary>
        [JsonIgnore]
        [NotMapped]
        [BsonIgnore]
        public TemporaryManager TemporaryManager
        {
            get { return TemporaryManager.Default; }
        }

        /// <summary>
        /// Occurs when a property has changed.
        /// </summary>
        [field: NonSerialized]
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Raises the property changed event.
        /// </summary>
        /// <param name="propName">Name of the property.</param>
        protected virtual void RaisePropertyChanged(String propName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        }

        /// <summary>
        /// Raises the property changed event.
        /// </summary>
        /// <param name="propName">Name of the property.</param>
        protected virtual void RaisePropertyChangedAuto([CallerMemberName] string caller = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(caller));
        }

        /// <summary>
        /// Raises all relay commands CanExecute methods in the current instance.
        /// </summary>
        protected virtual void InvalidateRelayCommands()
        {
            InvokeUI(() =>
            {
                foreach (var prop in this.GetType().GetProperties().Where(x => x.PropertyType == typeof(RelayCommand)))
                {
                    var value = prop.GetValue(this) as RelayCommand;

                    if (value != null)
                    {
                        value.RaiseCanExecuteChanged();
                    }
                }

                RelayCommandsInvalidated?.Invoke(this, new EventArgs());
            });
        }

        /// <summary>
        /// Gets a value indicating whether we are currently in VS design mode.
        /// </summary>
        [NotMapped]
        [JsonIgnore]
        [BsonIgnore]
        public bool DesignMode
        {
            get { return (DesignerProperties.GetIsInDesignMode(new DependencyObject())); }
        }

        /// <summary>
        /// Invokes the specified action on the UI Thread.
        /// </summary>
        /// <param name="action">The action.</param>
        protected virtual void InvokeUI(Action action)
        {
            if (Application.Current != null)
            {
                Application.Current.Dispatcher.BeginInvoke(action);
            }
            else
            {
                action();
            }
        }

        /// <summary>
        /// Invokes the specified action on the UI Thread when context is idle.
        /// </summary>
        /// <param name="action">The action.</param>
        protected virtual void InvokeUIOnIdle(Action action)
        {
            Application.Current.Dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
        }

        /// <summary>
        /// Invokes the specified action on the UI Thread.
        /// </summary>
        /// <param name="action">The action.</param>
        protected virtual void InvokeUINow(Action action)
        {
            Application.Current.Dispatcher.Invoke(action);
        }
    }
}