| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- // Copyright (c) The Avalonia Project. All rights reserved.
- // Licensed under the MIT license. See licence.md file in the project root for full license information.
- using System;
- using System.Reactive.Concurrency;
- using System.Threading;
- using Avalonia.Animation;
- using Avalonia.Controls;
- using Avalonia.Controls.ApplicationLifetimes;
- using Avalonia.Controls.Templates;
- using Avalonia.Input;
- using Avalonia.Input.Platform;
- using Avalonia.Input.Raw;
- using Avalonia.Platform;
- using Avalonia.Rendering;
- using Avalonia.Styling;
- using Avalonia.Threading;
- namespace Avalonia
- {
- /// <summary>
- /// Encapsulates a Avalonia application.
- /// </summary>
- /// <remarks>
- /// The <see cref="Application"/> class encapsulates Avalonia application-specific
- /// functionality, including:
- /// - A global set of <see cref="DataTemplates"/>.
- /// - A global set of <see cref="Styles"/>.
- /// - A <see cref="FocusManager"/>.
- /// - An <see cref="InputManager"/>.
- /// - Registers services needed by the rest of Avalonia in the <see cref="RegisterServices"/>
- /// method.
- /// - Tracks the lifetime of the application.
- /// </remarks>
- public class Application : AvaloniaObject, IDataContextProvider, IGlobalDataTemplates, IGlobalStyles, IResourceNode
- {
- /// <summary>
- /// The application-global data templates.
- /// </summary>
- private DataTemplates _dataTemplates;
- private readonly Lazy<IClipboard> _clipboard =
- new Lazy<IClipboard>(() => (IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard)));
- private readonly Styler _styler = new Styler();
- private Styles _styles;
- private IResourceDictionary _resources;
- private bool _notifyingResourcesChanged;
- /// <summary>
- /// Defines the <see cref="DataContext"/> property.
- /// </summary>
- public static readonly StyledProperty<object> DataContextProperty =
- StyledElement.DataContextProperty.AddOwner<Application>();
- /// <inheritdoc/>
- public event EventHandler<ResourcesChangedEventArgs> ResourcesChanged;
- /// <summary>
- /// Creates an instance of the <see cref="Application"/> class.
- /// </summary>
- public Application()
- {
- Name = "Avalonia Application";
- }
- /// <summary>
- /// Gets or sets the Applications's data context.
- /// </summary>
- /// <remarks>
- /// The data context property specifies the default object that will
- /// be used for data binding.
- /// </remarks>
- public object DataContext
- {
- get { return GetValue(DataContextProperty); }
- set { SetValue(DataContextProperty, value); }
- }
- /// <summary>
- /// Gets the current instance of the <see cref="Application"/> class.
- /// </summary>
- /// <value>
- /// The current instance of the <see cref="Application"/> class.
- /// </value>
- public static Application Current
- {
- get { return AvaloniaLocator.Current.GetService<Application>(); }
- }
- /// <summary>
- /// Gets or sets the application's global data templates.
- /// </summary>
- /// <value>
- /// The application's global data templates.
- /// </value>
- public DataTemplates DataTemplates => _dataTemplates ?? (_dataTemplates = new DataTemplates());
- /// <summary>
- /// Gets the application's focus manager.
- /// </summary>
- /// <value>
- /// The application's focus manager.
- /// </value>
- public IFocusManager FocusManager
- {
- get;
- private set;
- }
- /// <summary>
- /// Gets the application's input manager.
- /// </summary>
- /// <value>
- /// The application's input manager.
- /// </value>
- public InputManager InputManager
- {
- get;
- private set;
- }
- /// <summary>
- /// Gets the application clipboard.
- /// </summary>
- public IClipboard Clipboard => _clipboard.Value;
- /// <summary>
- /// Gets the application's global resource dictionary.
- /// </summary>
- public IResourceDictionary Resources
- {
- get => _resources ?? (Resources = new ResourceDictionary());
- set
- {
- Contract.Requires<ArgumentNullException>(value != null);
- var hadResources = false;
- if (_resources != null)
- {
- hadResources = _resources.Count > 0;
- _resources.ResourcesChanged -= ThisResourcesChanged;
- }
- _resources = value;
- _resources.ResourcesChanged += ThisResourcesChanged;
- if (hadResources || _resources.Count > 0)
- {
- ResourcesChanged?.Invoke(this, new ResourcesChangedEventArgs());
- }
- }
- }
- /// <summary>
- /// Gets the application's global styles.
- /// </summary>
- /// <value>
- /// The application's global styles.
- /// </value>
- /// <remarks>
- /// Global styles apply to all windows in the application.
- /// </remarks>
- public Styles Styles
- {
- get
- {
- if (_styles == null)
- {
- _styles = new Styles(this);
- _styles.ResourcesChanged += ThisResourcesChanged;
- }
- return _styles;
- }
- }
- /// <inheritdoc/>
- bool IDataTemplateHost.IsDataTemplatesInitialized => _dataTemplates != null;
- /// <summary>
- /// Gets the styling parent of the application, which is null.
- /// </summary>
- IStyleHost IStyleHost.StylingParent => null;
- /// <inheritdoc/>
- bool IStyleHost.IsStylesInitialized => _styles != null;
- /// <inheritdoc/>
- bool IResourceProvider.HasResources => _resources?.Count > 0;
- /// <inheritdoc/>
- IResourceNode IResourceNode.ResourceParent => null;
-
- /// <summary>
- /// Application lifetime, use it for things like setting the main window and exiting the app from code
- /// Currently supported lifetimes are:
- /// - <see cref="IClassicDesktopStyleApplicationLifetime"/>
- /// - <see cref="ISingleViewApplicationLifetime"/>
- /// - <see cref="IControlledApplicationLifetime"/>
- /// </summary>
- public IApplicationLifetime ApplicationLifetime { get; set; }
- /// <summary>
- /// Initializes the application by loading XAML etc.
- /// </summary>
- public virtual void Initialize() { }
- /// <inheritdoc/>
- bool IResourceProvider.TryGetResource(object key, out object value)
- {
- value = null;
- return (_resources?.TryGetResource(key, out value) ?? false) ||
- Styles.TryGetResource(key, out value);
- }
- /// <summary>
- /// Register's the services needed by Avalonia.
- /// </summary>
- public virtual void RegisterServices()
- {
- AvaloniaSynchronizationContext.InstallIfNeeded();
- FocusManager = new FocusManager();
- InputManager = new InputManager();
- AvaloniaLocator.CurrentMutable
- .Bind<IAccessKeyHandler>().ToTransient<AccessKeyHandler>()
- .Bind<IGlobalDataTemplates>().ToConstant(this)
- .Bind<IGlobalStyles>().ToConstant(this)
- .Bind<IFocusManager>().ToConstant(FocusManager)
- .Bind<IInputManager>().ToConstant(InputManager)
- .Bind<IKeyboardNavigationHandler>().ToTransient<KeyboardNavigationHandler>()
- .Bind<IStyler>().ToConstant(_styler)
- .Bind<IScheduler>().ToConstant(AvaloniaScheduler.Instance)
- .Bind<IDragDropDevice>().ToConstant(DragDropDevice.Instance)
- .Bind<IPlatformDragSource>().ToTransient<InProcessDragSource>();
- var clock = new RenderLoopClock();
- AvaloniaLocator.CurrentMutable
- .Bind<IGlobalClock>().ToConstant(clock)
- .GetService<IRenderLoop>()?.Add(clock);
- }
- public virtual void OnFrameworkInitializationCompleted()
- {
-
- }
- private void NotifyResourcesChanged(ResourcesChangedEventArgs e)
- {
- if (_notifyingResourcesChanged)
- {
- return;
- }
- try
- {
- _notifyingResourcesChanged = true;
- (_resources as ISetResourceParent)?.ParentResourcesChanged(e);
- (_styles as ISetResourceParent)?.ParentResourcesChanged(e);
- ResourcesChanged?.Invoke(this, new ResourcesChangedEventArgs());
- }
- finally
- {
- _notifyingResourcesChanged = false;
- }
- }
- private void ThisResourcesChanged(object sender, ResourcesChangedEventArgs e)
- {
- NotifyResourcesChanged(e);
- }
- private string _name;
- /// <summary>
- /// Defines Name property
- /// </summary>
- public static readonly DirectProperty<Application, string> NameProperty =
- AvaloniaProperty.RegisterDirect<Application, string>("Name", o => o.Name, (o, v) => o.Name = v);
- /// <summary>
- /// Application name to be used for various platform-specific purposes
- /// </summary>
- public string Name
- {
- get => _name;
- set => SetAndRaise(NameProperty, ref _name, value);
- }
- }
- }
|