diff options
author | Eric Maupin <ermaup@microsoft.com> | 2018-01-30 20:31:28 +0300 |
---|---|---|
committer | Eric Maupin <ermaup@microsoft.com> | 2018-01-30 20:31:28 +0300 |
commit | 8763a45dfc107e01aeb8c0b62223543d109f09e7 (patch) | |
tree | fafe3925cd23ccc172fc263f69208b92edb5a7e0 | |
parent | 6525ecfb70f5a4cde9ac891bef2f1b367c8e9b88 (diff) |
[Core/Windows] Pass around resource provider
4 files changed, 113 insertions, 66 deletions
diff --git a/Xamarin.PropertyEditing.Windows.Standalone/MainWindow.xaml.cs b/Xamarin.PropertyEditing.Windows.Standalone/MainWindow.xaml.cs index 0089d31..7fedb09 100644 --- a/Xamarin.PropertyEditing.Windows.Standalone/MainWindow.xaml.cs +++ b/Xamarin.PropertyEditing.Windows.Standalone/MainWindow.xaml.cs @@ -22,6 +22,7 @@ namespace Xamarin.PropertyEditing.Windows.Standalone } }; this.panel.EditorProvider = new MockEditorProvider (); + this.panel.ResourceProvider = new MockResourceProvider (); } private async void Button_Click (object sender, RoutedEventArgs e) diff --git a/Xamarin.PropertyEditing.Windows/PropertyEditorPanel.cs b/Xamarin.PropertyEditing.Windows/PropertyEditorPanel.cs index 1701c4a..e6202e4 100644 --- a/Xamarin.PropertyEditing.Windows/PropertyEditorPanel.cs +++ b/Xamarin.PropertyEditing.Windows/PropertyEditorPanel.cs @@ -27,7 +27,7 @@ namespace Xamarin.PropertyEditing.Windows } public static readonly DependencyProperty EditorProviderProperty = DependencyProperty.Register ( - nameof(EditorProvider), typeof(IEditorProvider), typeof(PropertyEditorPanel), new PropertyMetadata (default(IEditorProvider), (o, args) => ((PropertyEditorPanel)o).OnEditorProviderChanged())); + nameof(EditorProvider), typeof(IEditorProvider), typeof(PropertyEditorPanel), new PropertyMetadata (default(IEditorProvider), (o, args) => ((PropertyEditorPanel)o).OnProviderChanged())); public IEditorProvider EditorProvider { @@ -35,6 +35,15 @@ namespace Xamarin.PropertyEditing.Windows set { SetValue (EditorProviderProperty, value); } } + public static readonly DependencyProperty ResourceProviderProperty = DependencyProperty.Register ( + nameof(ResourceProvider), typeof(IResourceProvider), typeof(PropertyEditorPanel), new PropertyMetadata (default(IResourceProvider), (o, args) => ((PropertyEditorPanel)o).OnProviderChanged())); + + public IResourceProvider ResourceProvider + { + get { return (IResourceProvider) GetValue (ResourceProviderProperty); } + set { SetValue (ResourceProviderProperty, value); } + } + public static readonly DependencyProperty TargetPlatformProperty = DependencyProperty.Register ( "TargetPlatform", typeof(TargetPlatform), typeof(PropertyEditorPanel), new PropertyMetadata (TargetPlatform.Default)); @@ -86,7 +95,7 @@ namespace Xamarin.PropertyEditing.Windows this.paneSelector = (ChoiceControl) GetTemplateChild ("paneSelector"); this.paneSelector.SelectedValue = EditingPane.Properties; this.paneSelector.SelectedItemChanged += OnPaneChanged; - OnEditorProviderChanged(); + OnProviderChanged(); if (this.vm.SelectedObjects.Count > 0) OnArrangeModeChanged (ArrangeMode); @@ -142,7 +151,7 @@ namespace Xamarin.PropertyEditing.Windows OnArrangeModeChanged (ArrangeMode); } - private void OnEditorProviderChanged () + private void OnProviderChanged () { if (this.root == null) return; @@ -150,7 +159,14 @@ namespace Xamarin.PropertyEditing.Windows if (this.vm != null) this.vm.PropertyChanged -= OnVmPropertyChanged; - this.root.DataContext = this.vm = (EditorProvider != null) ? new PanelViewModel (EditorProvider, TargetPlatform) : null; + PanelViewModel newVm = null; + if (EditorProvider != null) { + newVm = new PanelViewModel (EditorProvider, TargetPlatform) { + ResourceProvider = ResourceProvider + }; + } + + this.root.DataContext = this.vm = newVm; if (this.vm != null) this.vm.PropertyChanged += OnVmPropertyChanged; diff --git a/Xamarin.PropertyEditing/ViewModels/PropertiesViewModel.cs b/Xamarin.PropertyEditing/ViewModels/PropertiesViewModel.cs index 52cd1f8..7526ece 100644 --- a/Xamarin.PropertyEditing/ViewModels/PropertiesViewModel.cs +++ b/Xamarin.PropertyEditing/ViewModels/PropertiesViewModel.cs @@ -28,6 +28,20 @@ namespace Xamarin.PropertyEditing.ViewModels public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; + public IResourceProvider ResourceProvider + { + get { return this.resourceProvider; } + set + { + if (this.resourceProvider == value) + return; + + this.resourceProvider = value; + UpdateResourceProvider(); + OnPropertyChanged(); + } + } + /// <remarks>Consumers should check for <see cref="INotifyCollectionChanged"/> and hook appropriately.</remarks> public IReadOnlyList<EditorViewModel> Properties => this.editors; @@ -200,6 +214,7 @@ namespace Xamarin.PropertyEditing.ViewModels { } + private IResourceProvider resourceProvider; private INameableObject nameable; private bool nameReadOnly; private bool eventsEnabled; @@ -404,6 +419,13 @@ namespace Xamarin.PropertyEditing.ViewModels return newEditors; } + private void UpdateResourceProvider() + { + foreach (PropertyViewModel vm in this.editors) { + vm.ResourceProvider = this.resourceProvider; + } + } + private void OnObjectEditorPropertiesChanged (object sender, NotifyCollectionChangedEventArgs e) { UpdateMembers(); @@ -411,6 +433,13 @@ namespace Xamarin.PropertyEditing.ViewModels private PropertyViewModel GetViewModel (IPropertyInfo property) { + var vm = GetViewModelCore (property); + vm.ResourceProvider = ResourceProvider; + return vm; + } + + private PropertyViewModel GetViewModelCore (IPropertyInfo property) + { Type[] interfaces = property.GetType ().GetInterfaces (); Type hasPredefinedValues = interfaces.FirstOrDefault (t => t.IsGenericType && t.GetGenericTypeDefinition () == typeof(IHavePredefinedValues<>)); diff --git a/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs b/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs index a727e7d..fcd8ae5 100644 --- a/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs +++ b/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs @@ -47,22 +47,6 @@ namespace Xamarin.PropertyEditing.ViewModels } } - public IReadOnlyList<Resource> Resources => this.resources; - - public IResourceProvider ResourceProvider - { - get { return this.resourceProvider; } - set - { - if (this.resourceProvider == value) - return; - - this.resourceProvider = value; - OnPropertyChanged (); - UpdateResources (); - } - } - protected virtual TValue ValidateValue (TValue validationValue) { return validationValue; @@ -107,11 +91,7 @@ namespace Xamarin.PropertyEditing.ViewModels } } - private readonly ObservableCollection<Resource> resources = new ObservableCollection<Resource> (); private ValueInfo<TValue> value; - private IResourceProvider resourceProvider; - private CancellationTokenSource cancelTokenSource; - private Task updateResourcesTask; private bool SetCurrentValue (ValueInfo<TValue> newValue) { @@ -160,14 +140,7 @@ namespace Xamarin.PropertyEditing.ViewModels private bool CanSetValueToResource (Resource resource) { - if (resource == null || !Property.CanWrite) - return false; - - // We're just going to block wait on this. There shouldn't be a scenario in which it would deadlock - // and we simply can't work async into the ICommand system. Looks bad, but practically shouldn't be an issue. - // Famous last words. - this.updateResourcesTask?.Wait (); - return this.resources.Contains (resource); + return (resource != null && SupportsResources); } private void OnSetValueToResource (Resource resource) @@ -181,38 +154,6 @@ namespace Xamarin.PropertyEditing.ViewModels }); } - private void UpdateResources () - { - var source = new CancellationTokenSource (); - var cancelSource = Interlocked.Exchange (ref this.cancelTokenSource, source); - cancelSource?.Cancel (); - - this.updateResourcesTask = UpdateResourcesAsync (source.Token); - } - - private async Task UpdateResourcesAsync (CancellationToken cancelToken) - { - this.resources.Clear(); - - var provider = this.resourceProvider; - if (provider != null) { - if (cancelToken.IsCancellationRequested) - return; - - try { - IReadOnlyList<Resource> gottenResources = await provider.GetResourcesAsync (Property, cancelToken); - if (cancelToken.IsCancellationRequested) - return; - - this.resources.AddItems (gottenResources); - } catch (OperationCanceledException) { - return; - } - } - - ((RelayCommand<Resource>)SetValueResourceCommand).ChangeCanExecute (); - } - private void OnClearValue () { SetValue (new ValueInfo<TValue> { @@ -238,8 +179,11 @@ namespace Xamarin.PropertyEditing.ViewModels Property = property; SetupConstraints (); + + this.requestResourceCommand = new RelayCommand (OnRequestResource, CanRequestResource); } + public event EventHandler<ResourceRequestedEventArgs> ResourceRequested; public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; public IPropertyInfo Property @@ -265,12 +209,45 @@ namespace Xamarin.PropertyEditing.ViewModels public virtual bool CanDelve => false; + public bool SupportsResources + { + get { return Property.CanWrite; } + } + + public IResourceProvider ResourceProvider + { + get { return this.resourceProvider; } + set + { + if (this.resourceProvider == value) + return; + + this.resourceProvider = value; + OnPropertyChanged (); + } + } + public ICommand SetValueResourceCommand { - get; - protected set; + get { return this.setValueResourceCommand; } + protected set + { + if (this.setValueResourceCommand == value) + return; + + if (this.setValueResourceCommand != null) + this.setValueResourceCommand.CanExecuteChanged -= OnSetValueResourceCommandCanExecuteChanged; + + this.setValueResourceCommand = value; + if (this.setValueResourceCommand != null) + this.setValueResourceCommand.CanExecuteChanged += OnSetValueResourceCommandCanExecuteChanged; + + ((RelayCommand)RequestResourceCommand).ChangeCanExecute(); + } } + public ICommand RequestResourceCommand => this.requestResourceCommand; + public ICommand ClearValueCommand { get; @@ -347,6 +324,9 @@ namespace Xamarin.PropertyEditing.ViewModels editor.PropertyChanged -= OnEditorPropertyChanged; } + private IResourceProvider resourceProvider; + private ICommand setValueResourceCommand; + private RelayCommand requestResourceCommand; private HashSet<IPropertyInfo> constraintProperties; private PropertyVariation variation; private string error; @@ -403,5 +383,26 @@ namespace Xamarin.PropertyEditing.ViewModels return true; } } + + private bool CanRequestResource () + { + return SupportsResources && SetValueResourceCommand != null; + } + + private void OnRequestResource () + { + var e = new ResourceRequestedEventArgs(); + ResourceRequested?.Invoke (this, e); + if (e.Resource == null) + return; + + if (SetValueResourceCommand.CanExecute (e.Resource)) + SetValueResourceCommand.Execute (e.Resource); + } + + private void OnSetValueResourceCommandCanExecuteChanged (object sender, EventArgs e) + { + this.requestResourceCommand.ChangeCanExecute(); + } } } |