diff options
18 files changed, 390 insertions, 54 deletions
diff --git a/Xamarin.PropertyEditing.Mac/Controls/ControlExtensions.cs b/Xamarin.PropertyEditing.Mac/Controls/ControlExtensions.cs new file mode 100644 index 0000000..3e94781 --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/Controls/ControlExtensions.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using AppKit; +using Foundation; +using Xamarin.PropertyEditing.ViewModels; + +namespace Xamarin.PropertyEditing.Mac +{ + internal static class ControlExtensions + { + public static Task<ITypeInfo> RequestAt (this TypeRequestedEventArgs self, IHostResourceProvider hostResources, NSView source, AsyncValue<IReadOnlyDictionary<IAssemblyInfo, ILookup<string, ITypeInfo>>> assignableTypes) + { + var tcs = new TaskCompletionSource<ITypeInfo> (); + + var vm = new TypeSelectorViewModel (assignableTypes); + var selector = new TypeSelectorControl { + ViewModel = vm, + Appearance = source.EffectiveAppearance + }; + + vm.PropertyChanged += (vms, ve) => { + if (ve.PropertyName == nameof (TypeSelectorViewModel.SelectedType)) { + tcs.TrySetResult (vm.SelectedType); + } + }; + + var popover = new NSPopover { + Behavior = NSPopoverBehavior.Transient, + Delegate = new PopoverDelegate<ITypeInfo> (tcs), + ContentViewController = new NSViewController { + View = selector, + PreferredContentSize = new CoreGraphics.CGSize (360, 335) + }, + }; + popover.SetAppearance (hostResources.GetVibrantAppearance (source.EffectiveAppearance)); + + tcs.Task.ContinueWith (t => { + popover.PerformClose (popover); + popover.Dispose (); + }, TaskScheduler.FromCurrentSynchronizationContext ()); + + popover.Show (source.Frame, source.Superview, NSRectEdge.MinYEdge); + return tcs.Task; + } + + private class PopoverDelegate<T> + : NSPopoverDelegate + { + public PopoverDelegate (TaskCompletionSource<T> tcs) + { + this.tcs = tcs; + } + + public override void WillClose (NSNotification notification) + { + this.tcs.TrySetCanceled (); + } + + private readonly TaskCompletionSource<T> tcs; + } + } +} diff --git a/Xamarin.PropertyEditing.Mac/Controls/ObjectEditorControl.cs b/Xamarin.PropertyEditing.Mac/Controls/ObjectEditorControl.cs index ab9749b..9e71316 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/ObjectEditorControl.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/ObjectEditorControl.cs @@ -110,38 +110,7 @@ namespace Xamarin.PropertyEditing.Mac private void OnTypeRequested (object sender, TypeRequestedEventArgs e) { - var tcs = new TaskCompletionSource<ITypeInfo> (); - e.SelectedType = tcs.Task; - - var vm = new TypeSelectorViewModel (ViewModel.AssignableTypes); - var selector = new TypeSelectorControl { - ViewModel = vm, - Appearance = EffectiveAppearance - }; - - vm.PropertyChanged += (vms, ve) => { - if (ve.PropertyName == nameof (TypeSelectorViewModel.SelectedType)) { - tcs.TrySetResult (vm.SelectedType); - } - }; - - var popover = new NSPopover { - Behavior = NSPopoverBehavior.Transient, - Delegate = new PopoverDelegate<ITypeInfo> (tcs), - ContentViewController = new NSViewController { - View = selector, - PreferredContentSize = new CoreGraphics.CGSize (360, 335) - }, - }; - - popover.SetAppearance (HostResources.GetVibrantAppearance (EffectiveAppearance)); - - tcs.Task.ContinueWith (t => { - popover.PerformClose (popover); - popover.Dispose (); - }, TaskScheduler.FromCurrentSynchronizationContext()); - - popover.Show (this.createObject.Frame, this, NSRectEdge.MinYEdge); + e.SelectedType = e.RequestAt (HostResources, this.createObject, ViewModel.AssignableTypes); } private void UpdateTypeLabel () @@ -164,21 +133,5 @@ namespace Xamarin.PropertyEditing.Mac { ViewModel.CreateInstanceCommand.Execute (null); } - - private class PopoverDelegate<T> - : NSPopoverDelegate - { - public PopoverDelegate (TaskCompletionSource<T> tcs) - { - this.tcs = tcs; - } - - public override void WillClose (NSNotification notification) - { - this.tcs.TrySetCanceled (); - } - - private readonly TaskCompletionSource<T> tcs; - } } } diff --git a/Xamarin.PropertyEditing.Mac/Controls/TypeEditorControl.cs b/Xamarin.PropertyEditing.Mac/Controls/TypeEditorControl.cs new file mode 100644 index 0000000..a7ca19e --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/Controls/TypeEditorControl.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Threading.Tasks; +using AppKit; +using Foundation; +using Xamarin.PropertyEditing.ViewModels; + +namespace Xamarin.PropertyEditing.Mac +{ + internal class TypeEditorControl + : PropertyEditorControl<TypePropertyViewModel> + { + public TypeEditorControl (IHostResourceProvider hostResources) + : base (hostResources) + { + this.typeLabel = new UnfocusableTextField { + TranslatesAutoresizingMaskIntoConstraints = false + }; + AddSubview (this.typeLabel); + + this.selectType = new NSButton { + Title = Properties.Resources.Select, + TranslatesAutoresizingMaskIntoConstraints = false, + BezelStyle = NSBezelStyle.Rounded + }; + this.selectType.Activated += OnSelectPressed; + AddSubview (this.selectType); + + this.buttonConstraint = NSLayoutConstraint.Create (this.selectType, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this.typeLabel, NSLayoutAttribute.Trailing, 1f, 12); + + AddConstraints (new[] { + NSLayoutConstraint.Create (this.typeLabel, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this, NSLayoutAttribute.Leading, 1f, 0f), + NSLayoutConstraint.Create (this.typeLabel, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, this, NSLayoutAttribute.CenterY, 1f, 0f), + NSLayoutConstraint.Create (this.typeLabel, NSLayoutAttribute.Height, NSLayoutRelation.Equal, this, NSLayoutAttribute.Height, 1, 0), + this.buttonConstraint, + NSLayoutConstraint.Create (this.selectType, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this, NSLayoutAttribute.Leading, 1, 0).WithPriority (NSLayoutPriority.DefaultLow), + NSLayoutConstraint.Create (this.selectType, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, this, NSLayoutAttribute.CenterY, 1f, 0f), + NSLayoutConstraint.Create (this.selectType, NSLayoutAttribute.Width, NSLayoutRelation.GreaterThanOrEqual, 1f, 70f), + }); + } + + public override NSView FirstKeyView => this.selectType; + + public override NSView LastKeyView => this.selectType; + + protected override void UpdateValue () + { + } + + protected override void UpdateErrorsDisplayed (IEnumerable errors) + { + } + + protected override void HandleErrorsChanged (object sender, DataErrorsChangedEventArgs e) + { + } + + protected override void SetEnabled () + { + this.selectType.Enabled = ViewModel.Property.CanWrite; + } + + protected override void UpdateAccessibilityValues () + { + this.selectType.AccessibilityTitle = String.Format (Properties.Resources.SelectTypeForProperty, ViewModel.Property.Name); + } + + protected override void OnViewModelChanged (PropertyViewModel oldModel) + { + base.OnViewModelChanged (oldModel); + + if (oldModel is TypePropertyViewModel tvm) { + tvm.TypeRequested -= OnTypeRequested; + } + + if (ViewModel != null) { + ViewModel.TypeRequested += OnTypeRequested; + + OnPropertyChanged (ViewModel, new PropertyChangedEventArgs (null)); + } + } + + protected override void OnPropertyChanged (object sender, PropertyChangedEventArgs e) + { + switch (e.PropertyName) { + case nameof (TypePropertyViewModel.Value): + UpdateTypeLabel (); + break; + case null: + case "": + UpdateTypeLabel (); + UpdateCreateInstanceCommand (); + break; + } + + base.OnPropertyChanged (sender, e); + } + + private readonly UnfocusableTextField typeLabel; + private readonly NSButton selectType; + private readonly NSLayoutConstraint buttonConstraint; + + private void OnCreateInstanceExecutableChanged (object sender, EventArgs e) + { + UpdateCreateInstanceCommand (); + } + + private void OnTypeRequested (object sender, TypeRequestedEventArgs e) + { + e.SelectedType = e.RequestAt (HostResources, this.selectType, ViewModel.AssignableTypes); + } + + private void UpdateTypeLabel () + { + if (ViewModel.Value == null) { + this.typeLabel.StringValue = String.Empty; + this.buttonConstraint.Active = false; + } else { + this.typeLabel.StringValue = $"({ViewModel.Value.Name})"; + this.buttonConstraint.Active = true; + } + } + + private void UpdateCreateInstanceCommand () + { + this.selectType.Enabled = ViewModel.SelectTypeCommand.CanExecute (null); + } + + private void OnSelectPressed (object sender, EventArgs e) + { + ViewModel.SelectTypeCommand.Execute (null); + } + + private class PopoverDelegate<T> + : NSPopoverDelegate + { + public PopoverDelegate (TaskCompletionSource<T> tcs) + { + this.tcs = tcs; + } + + public override void WillClose (NSNotification notification) + { + this.tcs.TrySetCanceled (); + } + + private readonly TaskCompletionSource<T> tcs; + } + } +} diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs b/Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs index cb96191..29bc5b2 100644 --- a/Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs +++ b/Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs @@ -55,6 +55,7 @@ namespace Xamarin.PropertyEditing.Mac {typeof (ThicknessPropertyViewModel), typeof (CommonThicknessEditorControl) }, {typeof (PropertyGroupViewModel), typeof (GroupEditorControl)}, {typeof (ObjectPropertyViewModel), typeof (ObjectEditorControl)}, + {typeof (TypePropertyViewModel), typeof (TypeEditorControl)}, }; } diff --git a/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj b/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj index ef68417..5573e89 100644 --- a/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj +++ b/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj @@ -149,6 +149,8 @@ <Compile Include="Controls\TypeSelectorControl.cs" />
<Compile Include="Controls\TypeSelectorWindow.cs" />
<Compile Include="Controls\Custom\PropertyTextField.cs" />
+ <Compile Include="Controls\ControlExtensions.cs" />
+ <Compile Include="Controls\TypeEditorControl.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Controls\" />
diff --git a/Xamarin.PropertyEditing.Tests/MockControls/MockControl.cs b/Xamarin.PropertyEditing.Tests/MockControls/MockControl.cs index 66795a8..585bb7f 100644 --- a/Xamarin.PropertyEditing.Tests/MockControls/MockControl.cs +++ b/Xamarin.PropertyEditing.Tests/MockControls/MockControl.cs @@ -15,7 +15,7 @@ namespace Xamarin.PropertyEditing.Tests.MockControls bool canWrite = true, bool flag = false, IEnumerable<Type> converterTypes = null, string description = null, bool constrained = true, ValueSources valueSources = ValueSources.Local | ValueSources.Default | ValueSources.Binding, - IReadOnlyList<InputMode> inputModes = null, PropertyVariationOption[] options = null, bool isUncommon = false) + IReadOnlyList<InputMode> inputModes = null, PropertyVariationOption[] options = null, bool isUncommon = false, ITypeInfo realType = null) { IPropertyInfo propertyInfo; if (typeof(T).IsEnum) { @@ -26,7 +26,7 @@ namespace Xamarin.PropertyEditing.Tests.MockControls } else if (inputModes != null) { propertyInfo = new MockPropertyInfoWithInputTypes<T> (name, inputModes, description, category, canWrite, converterTypes, valueSources, options); } else { - propertyInfo = new MockPropertyInfo<T> (name, description, category, canWrite, converterTypes, valueSources, options, isUncommon); + propertyInfo = new MockPropertyInfo<T> (name, description, category, canWrite, converterTypes, valueSources, options, isUncommon, realType); } AddProperty<T> (propertyInfo); diff --git a/Xamarin.PropertyEditing.Tests/MockControls/MockSampleControl.cs b/Xamarin.PropertyEditing.Tests/MockControls/MockSampleControl.cs index b92fb13..7e1a8a8 100644 --- a/Xamarin.PropertyEditing.Tests/MockControls/MockSampleControl.cs +++ b/Xamarin.PropertyEditing.Tests/MockControls/MockSampleControl.cs @@ -37,6 +37,7 @@ namespace Xamarin.PropertyEditing.Tests.MockControls AddProperty<CommonThickness> ("Thickness", ReadWrite); AddProperty<object> ("Object", ReadWrite); AddProperty<IList> ("Collection", ReadWrite); + AddProperty<ITypeInfo> ("Type", ReadWrite, realType: typeof(Type).ToTypeInfo()); AddReadOnlyProperty<bool> ("ReadOnlyBoolean", ReadOnly); AddReadOnlyProperty<int> ("ReadOnlyInteger", ReadOnly); diff --git a/Xamarin.PropertyEditing.Tests/MockPropertyInfo/MockPropertyInfo.cs b/Xamarin.PropertyEditing.Tests/MockPropertyInfo/MockPropertyInfo.cs index 9a3ea41..c155b90 100644 --- a/Xamarin.PropertyEditing.Tests/MockPropertyInfo/MockPropertyInfo.cs +++ b/Xamarin.PropertyEditing.Tests/MockPropertyInfo/MockPropertyInfo.cs @@ -23,7 +23,7 @@ namespace Xamarin.PropertyEditing.Tests.MockPropertyInfo public class MockPropertyInfo<T> : IPropertyInfo, IPropertyConverter, IEquatable<MockPropertyInfo<T>> { - public MockPropertyInfo (string name, string description = null, string category = null, bool canWrite = true, IEnumerable<Type> converterTypes = null, ValueSources valueSources = ValueSources.Local | ValueSources.Default, PropertyVariationOption[] options = null, bool isUncommon = false) + public MockPropertyInfo (string name, string description = null, string category = null, bool canWrite = true, IEnumerable<Type> converterTypes = null, ValueSources valueSources = ValueSources.Local | ValueSources.Default, PropertyVariationOption[] options = null, bool isUncommon = false, ITypeInfo realType = null) { Name = name; Description = description; @@ -43,13 +43,18 @@ namespace Xamarin.PropertyEditing.Tests.MockPropertyInfo } Variations = options ?? EmptyVariationOptions; + RealType = realType ?? typeof (T).ToTypeInfo (); } public string Name { get; } public string Description { get; } public virtual Type Type => typeof (T); - public virtual ITypeInfo RealType => typeof(T).ToTypeInfo (); + public ITypeInfo RealType + { + get; + private set; + } public string Category { get; } public bool CanWrite { get; } diff --git a/Xamarin.PropertyEditing.Windows/EditorPropertySelector.cs b/Xamarin.PropertyEditing.Windows/EditorPropertySelector.cs index 45994e4..57c5e59 100644 --- a/Xamarin.PropertyEditing.Windows/EditorPropertySelector.cs +++ b/Xamarin.PropertyEditing.Windows/EditorPropertySelector.cs @@ -108,6 +108,7 @@ namespace Xamarin.PropertyEditing.Windows { typeof(BrushPropertyViewModel), typeof(BrushEditorControl) }, { typeof(PropertyGroupViewModel), typeof(GroupEditorControl) }, { typeof(ObjectPropertyViewModel), typeof(ObjectEditorControl) }, + { typeof(TypePropertyViewModel), typeof(TypeEditorControl) }, { typeof(CollectionPropertyViewModel), typeof(CollectionEditor) }, { typeof(RatioViewModel), typeof(RatioEditorControl) }, }; diff --git a/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml b/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml index 7715277..33c9087 100644 --- a/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml +++ b/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml @@ -417,7 +417,25 @@ </Grid.ColumnDefinitions> <TextBlock Text="{Binding ValueType.Name,StringFormat=({0})}" Grid.Column="0" VerticalAlignment="Center" /> - <Button AutomationProperties.Name="{Binding Property.Name,Mode=OneTime,StringFormat={x:Static prop:Resources.NewInstanceForProperty}}" MinHeight="20" MinWidth="40" Grid.Column="1" HorizontalAlignment="Right" Content="{x:Static prop:Resources.New}" Command="{Binding CreateInstanceCommand}" /> + <Button AutomationProperties.Name="{Binding Property.Name,Mode=OneTime,StringFormat={x:Static prop:Resources.NewInstanceForProperty}}" MinHeight="20" MinWidth="40" Grid.Column="1" HorizontalAlignment="Right" Content="{x:Static prop:Resources.New}" Command="{Binding CreateInstanceCommand,Mode=OneTime}" /> + </Grid> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + + <Style TargetType="local:TypeEditorControl"> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="local:TypeEditorControl"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + + <TextBlock Text="{Binding Value.Name,StringFormat=({0})}" Grid.Column="0" VerticalAlignment="Center" /> + <Button AutomationProperties.Name="{Binding Property.Name,Mode=OneTime,StringFormat={x:Static prop:Resources.SelectTypeForProperty}}" MinHeight="20" MinWidth="40" Grid.Column="1" HorizontalAlignment="Right" Content="{x:Static prop:Resources.Select}" Command="{Binding SelectTypeCommand,Mode=OneTime}" /> </Grid> </ControlTemplate> </Setter.Value> diff --git a/Xamarin.PropertyEditing.Windows/TypeEditorControl.cs b/Xamarin.PropertyEditing.Windows/TypeEditorControl.cs new file mode 100644 index 0000000..4fd3575 --- /dev/null +++ b/Xamarin.PropertyEditing.Windows/TypeEditorControl.cs @@ -0,0 +1,42 @@ +using System.Threading.Tasks; +using System.Windows; +using Xamarin.PropertyEditing.ViewModels; + +namespace Xamarin.PropertyEditing.Windows +{ + internal class TypeEditorControl + : PropertyEditorControl + { + static TypeEditorControl () + { + DefaultStyleKeyProperty.OverrideMetadata (typeof (TypeEditorControl), new FrameworkPropertyMetadata (typeof (TypeEditorControl))); + } + + public TypeEditorControl () + { + DataContextChanged += OnDataContextChanged; + } + + private TypePropertyViewModel vm; + + private void OnDataContextChanged (object sender, DependencyPropertyChangedEventArgs e) + { + if (this.vm != null) + this.vm.TypeRequested -= OnTypeRequested; + + this.vm = e.NewValue as TypePropertyViewModel; + if (this.vm != null) + this.vm.TypeRequested += OnTypeRequested; + } + + private void OnTypeRequested (object sender, TypeRequestedEventArgs e) + { + var vsender = (TypePropertyViewModel)sender; + + var panel = this.FindPropertiesHost (); + + ITypeInfo type = TypeSelectorWindow.RequestType (panel, vsender.AssignableTypes); + e.SelectedType = Task.FromResult (type); + } + } +} diff --git a/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj b/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj index e29b504..bef6888 100644 --- a/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj +++ b/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj @@ -142,6 +142,7 @@ <Compile Include="ThicknessEditorControl.cs" /> <Compile Include="StringEditorControl.cs" /> <Compile Include="TreeViewItemEx.cs" /> + <Compile Include="TypeEditorControl.cs" /> <Compile Include="TypeSelectorControl.xaml.cs"> <DependentUpon>TypeSelectorControl.xaml</DependentUpon> </Compile> diff --git a/Xamarin.PropertyEditing/Properties/Resources.Designer.cs b/Xamarin.PropertyEditing/Properties/Resources.Designer.cs index 7a52edb..1249b10 100644 --- a/Xamarin.PropertyEditing/Properties/Resources.Designer.cs +++ b/Xamarin.PropertyEditing/Properties/Resources.Designer.cs @@ -1141,6 +1141,15 @@ namespace Xamarin.PropertyEditing.Properties { } /// <summary> + /// Looks up a localized string similar to Select. + /// </summary> + public static string Select { + get { + return ResourceManager.GetString("Select", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to Select Object. /// </summary> public static string SelectObjectTitle { @@ -1159,6 +1168,15 @@ namespace Xamarin.PropertyEditing.Properties { } /// <summary> + /// Looks up a localized string similar to Select {0} type. + /// </summary> + public static string SelectTypeForProperty { + get { + return ResourceManager.GetString("SelectTypeForProperty", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to Shared. /// </summary> public static string Shared { diff --git a/Xamarin.PropertyEditing/Properties/Resources.resx b/Xamarin.PropertyEditing/Properties/Resources.resx index 168c1eb..9e44bbd 100644 --- a/Xamarin.PropertyEditing/Properties/Resources.resx +++ b/Xamarin.PropertyEditing/Properties/Resources.resx @@ -570,4 +570,11 @@ <value>New {0}</value> <comment>New {PropertyName}</comment> </data> + <data name="Select" xml:space="preserve"> + <value>Select</value> + </data> + <data name="SelectTypeForProperty" xml:space="preserve"> + <value>Select {0} type</value> + <comment>Select {property} type</comment> + </data> </root>
\ No newline at end of file diff --git a/Xamarin.PropertyEditing/Reflection/ReflectionObjectEditor.cs b/Xamarin.PropertyEditing/Reflection/ReflectionObjectEditor.cs index 3ea7209..a7fbbc5 100644 --- a/Xamarin.PropertyEditing/Reflection/ReflectionObjectEditor.cs +++ b/Xamarin.PropertyEditing/Reflection/ReflectionObjectEditor.cs @@ -159,7 +159,8 @@ namespace Xamarin.PropertyEditing.Reflection } } - types = types.Where (t => realType.IsAssignableFrom (t)); + if (realType != typeof(Type)) + types = types.Where (t => realType.IsAssignableFrom (t)); return new AssignableTypesResult (types.Select (t => { string asmName = t.Assembly.GetName ().Name; diff --git a/Xamarin.PropertyEditing/ViewModels/PropertiesViewModel.cs b/Xamarin.PropertyEditing/ViewModels/PropertiesViewModel.cs index 0ee785b..7ddae70 100644 --- a/Xamarin.PropertyEditing/ViewModels/PropertiesViewModel.cs +++ b/Xamarin.PropertyEditing/ViewModels/PropertiesViewModel.cs @@ -614,6 +614,7 @@ namespace Xamarin.PropertyEditing.ViewModels { typeof(BindingSource), (tp,p,e,v) => new PropertyViewModel<BindingSource> (tp, p, e, v) }, { typeof(Resource), (tp,p,e,v) => new PropertyViewModel<Resource> (tp, p, e, v) }, { typeof(object), (tp,p,e,v) => new ObjectPropertyViewModel (tp, p, e, v) }, + { typeof(ITypeInfo), (tp,p,e,v) => new TypePropertyViewModel (tp, p, e, v) }, { typeof(CommonRatio), (tp, p, e, v) => new RatioViewModel (tp, p, e, v) }, }; } diff --git a/Xamarin.PropertyEditing/ViewModels/TypePropertyViewModel.cs b/Xamarin.PropertyEditing/ViewModels/TypePropertyViewModel.cs new file mode 100644 index 0000000..fe192d9 --- /dev/null +++ b/Xamarin.PropertyEditing/ViewModels/TypePropertyViewModel.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace Xamarin.PropertyEditing.ViewModels +{ + internal class TypePropertyViewModel + : PropertyViewModel<ITypeInfo> + { + public TypePropertyViewModel (TargetPlatform platform, IPropertyInfo propertyInfo, IEnumerable<IObjectEditor> editors, PropertyVariation variation = null) + : base (platform, propertyInfo, editors, variation) + { + SelectTypeCommand = new RelayCommand (SetType, () => Property.CanWrite); + } + + public event EventHandler<TypeRequestedEventArgs> TypeRequested; + + public ICommand SelectTypeCommand + { + get; + } + + public AsyncValue<IReadOnlyDictionary<IAssemblyInfo, ILookup<string, ITypeInfo>>> AssignableTypes + { + get + { + if (this.assignableTypes == null) + this.assignableTypes = new AsyncValue<IReadOnlyDictionary<IAssemblyInfo, ILookup<string, ITypeInfo>>> (GetAssignableTypesAsync ()); + + return this.assignableTypes; + } + } + + private AsyncValue<IReadOnlyDictionary<IAssemblyInfo, ILookup<string, ITypeInfo>>> assignableTypes; + + private async Task<IReadOnlyDictionary<IAssemblyInfo, ILookup<string, ITypeInfo>>> GetAssignableTypesAsync () + { + AssignableTypesResult result = await Editors.GetCommonAssignableTypes (Property, childTypes: false).ConfigureAwait (false); + return result.GetTypeTree (); + } + + private async void SetType () + { + using (await AsyncWork.RequestAsyncWork (this)) { + ITypeInfo selectedType = null; + var args = new TypeRequestedEventArgs (); + TypeRequested?.Invoke (this, args); + if (args.SelectedType == null) + return; + + try { + selectedType = await args.SelectedType; + if (selectedType == null) + return; + } catch (OperationCanceledException) { + return; + } + + await SetValueAsync (new ValueInfo<ITypeInfo> { + Value = selectedType, + Source = ValueSource.Local + }); + } + } + } +} diff --git a/Xamarin.PropertyEditing/Xamarin.PropertyEditing.csproj b/Xamarin.PropertyEditing/Xamarin.PropertyEditing.csproj index 35df7c9..b638f30 100644 --- a/Xamarin.PropertyEditing/Xamarin.PropertyEditing.csproj +++ b/Xamarin.PropertyEditing/Xamarin.PropertyEditing.csproj @@ -165,6 +165,7 @@ <Compile Include="ViewModels\RectanglePropertyViewModel.cs" /> <Compile Include="ViewModels\ThicknessPropertyViewModel.cs" /> <Compile Include="ViewModels\ObjectTreeElement.cs" /> + <Compile Include="ViewModels\TypePropertyViewModel.cs" /> <Compile Include="ViewModels\TypeSelectorViewModel.cs" /> <Compile Include="ViewModels\RatioViewModel.cs" /> <Compile Include="Drawing\CommonRatio.cs" /> |