diff options
17 files changed, 1964 insertions, 283 deletions
diff --git a/Xamarin.PropertyEditing.Tests/CreateResourceViewModelTests.cs b/Xamarin.PropertyEditing.Tests/CreateResourceViewModelTests.cs new file mode 100644 index 0000000..79c6727 --- /dev/null +++ b/Xamarin.PropertyEditing.Tests/CreateResourceViewModelTests.cs @@ -0,0 +1,548 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Moq; +using NUnit.Framework; +using NUnit.Framework.Internal; +using Xamarin.PropertyEditing.ViewModels; + +namespace Xamarin.PropertyEditing.Tests +{ + [TestFixture] + public class CreateResourceViewModelTests + { + [Test] + public void ApplicationSources () + { + var target = new object(); + var property = new Mock<IPropertyInfo>(); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (Sources); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + Assert.That (vm.HasApplicationSources, Is.True, "HasApplicationSources is false"); + Assert.That (vm.ApplicationSources.Count, Is.EqualTo (2), "Incorrect number of items"); + Assert.That (vm.ApplicationSources, Contains.Item (Sources[1])); + Assert.That (vm.ApplicationSources, Contains.Item (Sources[2])); + } + + [Test] + public void DocumentSources () + { + var target = new object(); + var property = new Mock<IPropertyInfo>(); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (Sources); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + Assert.That (vm.HasDocumentSources, Is.True, "HasDocumentSources is false"); + Assert.That (vm.ApplicationSources.Count, Is.EqualTo (2), "Incorrect number of items"); + Assert.That (vm.DocumentSources, Contains.Item (Sources[3])); + Assert.That (vm.DocumentSources, Contains.Item (Sources[4])); + } + + [Test] + public void IsKeyed () + { + var target = new object(); + var property = new Mock<IPropertyInfo>(); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (new[] { + new ResourceSource ("app", ResourceSourceType.Application) + }); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + Assert.That (vm.IsKeyed, Is.True); + Assert.That (vm.IsAppliedToAll, Is.False); + + bool namedChanged = false, allChanged = false; + vm.PropertyChanged += (o, e) => { + if (e.PropertyName == nameof(CreateResourceViewModel.IsAppliedToAll)) + allChanged = true; + else if (e.PropertyName == nameof(CreateResourceViewModel.IsKeyed)) + namedChanged = true; + }; + + vm.IsKeyed = false; + Assert.That (vm.IsKeyed, Is.False); + Assert.That (vm.IsAppliedToAll, Is.True); + Assert.That (namedChanged, Is.True); + Assert.That (allChanged, Is.True); + namedChanged = allChanged = false; + + vm.IsKeyed = true; + Assert.That (vm.IsKeyed, Is.True); + Assert.That (vm.IsAppliedToAll, Is.False); + Assert.That (namedChanged, Is.True); + Assert.That (allChanged, Is.True); + } + + [Test] + public void IsAppliedToAll () + { + var target = new object(); + var property = new Mock<IPropertyInfo>(); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (new[] { + new ResourceSource ("app", ResourceSourceType.Application) + }); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + Assert.That (vm.IsKeyed, Is.True); + Assert.That (vm.IsAppliedToAll, Is.False); + + bool namedChanged = false, allChanged = false; + vm.PropertyChanged += (o, e) => { + if (e.PropertyName == nameof(CreateResourceViewModel.IsAppliedToAll)) + allChanged = true; + else if (e.PropertyName == nameof(CreateResourceViewModel.IsKeyed)) + namedChanged = true; + }; + + vm.IsAppliedToAll = true; + Assert.That (vm.IsKeyed, Is.False); + Assert.That (vm.IsAppliedToAll, Is.True); + Assert.That (namedChanged, Is.True); + Assert.That (allChanged, Is.True); + namedChanged = allChanged = false; + + vm.IsAppliedToAll = false; + Assert.That (vm.IsKeyed, Is.True); + Assert.That (vm.IsAppliedToAll, Is.False); + Assert.That (namedChanged, Is.True); + Assert.That (allChanged, Is.True); + } + + [Test] + public void IsLoading () + { + var tcs = new TaskCompletionSource<IReadOnlyList<ResourceSource>> (); + + var target = new object(); + var property = new Mock<IPropertyInfo>(); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).Returns (tcs.Task); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + Assert.That (vm.IsLoading, Is.True); + + bool isLoadingChanged = false; + vm.PropertyChanged += (o, e) => { + if (e.PropertyName == nameof(CreateResourceViewModel.IsLoading)) + isLoadingChanged = true; + }; + + tcs.SetResult (new[] { new ResourceSource ("app", ResourceSourceType.Application) }); + Assert.That (isLoadingChanged, Is.True); + Assert.That (vm.IsLoading, Is.False); + } + + [Test] + public void FatalError () + { + var tcs = new TaskCompletionSource<IReadOnlyList<ResourceSource>> (); + + var target = new object(); + var property = new Mock<IPropertyInfo>(); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).Returns (tcs.Task); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + Assume.That (vm.HasFatalError, Is.False); + Assume.That (vm.FatalError, Is.Null); + + bool hasErrorChanged = false, errorChanged = false; + vm.PropertyChanged += (o, e) => { + if (e.PropertyName == nameof(CreateResourceViewModel.FatalError)) + errorChanged = true; + if (e.PropertyName == nameof(CreateResourceViewModel.HasFatalError)) + hasErrorChanged = true; + }; + + const string errorMessage = "test"; + tcs.SetException (new Exception (errorMessage)); + Assert.That (hasErrorChanged, Is.True); + Assert.That (errorChanged, Is.True); + Assert.That (vm.HasFatalError, Is.True); + Assert.That (vm.FatalError, Is.EqualTo (errorMessage)); + } + + [Test] + public void DefineInApplication () + { + var target = new object(); + var property = new Mock<IPropertyInfo>(); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (Sources); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + Assume.That (vm.DocumentSources, Is.Not.Empty); + Assert.That (vm.SelectedResourceSource, Is.EqualTo (Sources[0])); + Assert.That (vm.DefineInApplication, Is.True); + Assert.That (vm.DefineInDocument, Is.False); + Assert.That (vm.DefineInApplicationSource, Is.False); + + bool inAppChanged = false, inDictChanged = false, inDocumentChanged = false, selectedSourceChanged = false; + vm.PropertyChanged += (o, e) => { + if (e.PropertyName == nameof(CreateResourceViewModel.DefineInApplicationSource)) + inDictChanged = true; + else if (e.PropertyName == nameof(CreateResourceViewModel.DefineInApplication)) + inAppChanged = true; + else if (e.PropertyName == nameof(CreateResourceViewModel.DefineInDocument)) + inDocumentChanged = true; + else if (e.PropertyName == nameof(CreateResourceViewModel.SelectedResourceSource)) + selectedSourceChanged = true; + }; + + vm.DefineInApplication = false; + Assert.That (vm.DefineInApplication, Is.False); + Assert.That (vm.DefineInDocument, Is.True); + Assert.That (vm.DefineInApplicationSource, Is.False); + Assert.That (vm.SelectedResourceSource, Is.EqualTo (Sources[3])); + Assert.That (selectedSourceChanged, Is.True); + Assert.That (inAppChanged, Is.True); + Assert.That (inDocumentChanged, Is.True); + inAppChanged = inDictChanged = inDocumentChanged = selectedSourceChanged = false; + + vm.DefineInApplication = true; + Assert.That (vm.DefineInApplication, Is.True); + Assert.That (vm.DefineInDocument, Is.False); + Assert.That (vm.DefineInApplicationSource, Is.False); + Assert.That (vm.SelectedResourceSource, Is.EqualTo (Sources[0])); + Assert.That (selectedSourceChanged, Is.True); + Assert.That (inAppChanged, Is.True); + Assert.That (inDocumentChanged, Is.True); + } + + [Test] + public void DefineInDocument () + { + var target = new object(); + var property = new Mock<IPropertyInfo>(); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (Sources); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + Assume.That (vm.DocumentSources, Is.Not.Empty); + Assume.That (vm.SelectedResourceSource, Is.EqualTo (Sources[0])); + Assume.That (vm.DefineInApplication, Is.True); + Assume.That (vm.DefineInDocument, Is.False); + Assume.That (vm.DefineInApplicationSource, Is.False); + + bool inAppChanged = false, inDictChanged = false, inDocumentChanged = false, selectedSourceChanged = false; + vm.PropertyChanged += (o, e) => { + if (e.PropertyName == nameof(CreateResourceViewModel.DefineInApplicationSource)) + inDictChanged = true; + else if (e.PropertyName == nameof(CreateResourceViewModel.DefineInApplication)) + inAppChanged = true; + else if (e.PropertyName == nameof(CreateResourceViewModel.DefineInDocument)) + inDocumentChanged = true; + else if (e.PropertyName == nameof(CreateResourceViewModel.SelectedResourceSource)) + selectedSourceChanged = true; + }; + + vm.DefineInDocument = true; + Assert.That (vm.DefineInApplication, Is.False); + Assert.That (vm.DefineInDocument, Is.True); + Assert.That (vm.DefineInApplicationSource, Is.False); + Assert.That (vm.SelectedResourceSource, Is.EqualTo (Sources[3])); + Assert.That (selectedSourceChanged, Is.True); + Assert.That (inAppChanged, Is.True); + Assert.That (inDocumentChanged, Is.True); + inAppChanged = inDictChanged = inDocumentChanged = selectedSourceChanged = false; + + vm.DefineInDocument = false; + Assert.That (vm.DefineInApplication, Is.True); + Assert.That (vm.DefineInDocument, Is.False); + Assert.That (vm.DefineInApplicationSource, Is.False); + Assert.That (vm.SelectedResourceSource, Is.EqualTo (Sources[0])); + Assert.That (selectedSourceChanged, Is.True); + Assert.That (inAppChanged, Is.True); + Assert.That (inDocumentChanged, Is.True); + } + + [Test] + public void DefineInApplicationSource () + { + var target = new object(); + var property = new Mock<IPropertyInfo>(); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (Sources); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + Assume.That (vm.ApplicationSources, Is.Not.Empty); + Assume.That (vm.SelectedResourceSource, Is.EqualTo (Sources[0])); + Assume.That (vm.DefineInApplication, Is.True); + Assume.That (vm.DefineInDocument, Is.False); + Assume.That (vm.DefineInApplicationSource, Is.False); + + bool inAppChanged = false, inDictChanged = false, inDocumentChanged = false, selectedSourceChanged = false; + vm.PropertyChanged += (o, e) => { + if (e.PropertyName == nameof(CreateResourceViewModel.DefineInApplicationSource)) + inDictChanged = true; + else if (e.PropertyName == nameof(CreateResourceViewModel.DefineInApplication)) + inAppChanged = true; + else if (e.PropertyName == nameof(CreateResourceViewModel.DefineInDocument)) + inDocumentChanged = true; + else if (e.PropertyName == nameof(CreateResourceViewModel.SelectedResourceSource)) + selectedSourceChanged = true; + }; + + vm.DefineInApplicationSource = true; + Assert.That (vm.DefineInApplication, Is.False); + Assert.That (vm.DefineInDocument, Is.False); + Assert.That (vm.DefineInApplicationSource, Is.True); + Assert.That (vm.SelectedResourceSource, Is.EqualTo (Sources[1])); + Assert.That (selectedSourceChanged, Is.True); + Assert.That (inAppChanged, Is.True); + Assert.That (inDictChanged, Is.True); + inAppChanged = inDictChanged = inDocumentChanged = selectedSourceChanged = false; + + vm.DefineInApplicationSource = false; + Assert.That (vm.DefineInApplication, Is.True); + Assert.That (vm.DefineInDocument, Is.False); + Assert.That (vm.DefineInApplicationSource, Is.False); + Assert.That (vm.SelectedResourceSource, Is.EqualTo (Sources[0])); + Assert.That (selectedSourceChanged, Is.True); + Assert.That (inAppChanged, Is.True); + Assert.That (inDictChanged, Is.True); + } + + [Test] + public void CreateResourceCommand () + { + var target = new object(); + var property = new Mock<IPropertyInfo>(); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (Sources); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + Assume.That (vm.IsKeyed, Is.True); + Assume.That (vm.ResourceKey, Is.Null); + Assume.That (vm.DefineInApplication, Is.True); + + Assert.That (vm.CreateResourceCommand.CanExecute (null), Is.False); + + bool changed = false; + vm.CreateResourceCommand.CanExecuteChanged += (o, e) => { + changed = true; + }; + + vm.ResourceKey = "name"; + + Assert.That (changed, Is.True); + Assert.That (vm.CreateResourceCommand.CanExecute (null), Is.True); + + bool create = false; + vm.CreateResource += (o, e) => { + create = true; + }; + + vm.CreateResourceCommand.Execute (null); + Assert.That (create, Is.True); + } + + [Test] + public void NameError () + { + var target = new object(); + var property = new Mock<IPropertyInfo>(); + property.SetupGet (pi => pi.Type).Returns (typeof(string)); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (Sources); + provider.Setup (p => p.CheckNameErrorsAsync (target, It.IsAny<ResourceSource> (), It.IsAny<string> ())) + .ReturnsAsync (new ResourceCreateError ("failed", false)); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + bool changed = false; + vm.ErrorsChanged += (sender, args) => { + if (args.PropertyName == nameof(CreateResourceViewModel.ResourceKey)) + changed = true; + }; + + bool hasErrorsChanged = false; + vm.PropertyChanged += (sender, args) => { + if (args.PropertyName == nameof(CreateResourceViewModel.HasErrors)) + hasErrorsChanged = true; + }; + + vm.ResourceKey = "Test"; + Assert.That (changed, Is.True, "ErrorsChanged did not fire"); + Assert.That (vm.HasErrors, Is.True); + Assert.That (hasErrorsChanged, Is.True, "HasErrors did not change"); + Assert.That (vm.GetErrors (nameof(CreateResourceViewModel.ResourceKey)), Contains.Item ("failed")); + } + + [Test] + public void ErrorCheckOnSourceChange () + { + const string error = "failed"; + const string invalidName = "test"; + var target = new object(); + var property = new Mock<IPropertyInfo>(); + property.SetupGet (pi => pi.Type).Returns (typeof(string)); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (Sources); + provider.Setup (p => p.CheckNameErrorsAsync (target, It.Is<ResourceSource> (r => r == Sources[0]), invalidName)) + .ReturnsAsync (new ResourceCreateError (error, false)); + + provider.Setup (p => p.CheckNameErrorsAsync (target, It.Is<ResourceSource> (r => r == Sources[1] || r == Sources[2]), invalidName)) + .ReturnsAsync ((ResourceCreateError)null); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + Assume.That (vm.SelectedResourceSource, Is.EqualTo (Sources[0])); + Assume.That (vm.HasErrors, Is.False); + + bool errorsChanged = false; + vm.ErrorsChanged += (sender, args) => { + if (args.PropertyName == nameof(CreateResourceViewModel.ResourceKey)) + errorsChanged = true; + }; + + bool hasErrorsChanged = false; + vm.PropertyChanged += (sender, args) => { + if (args.PropertyName == nameof(CreateResourceViewModel.HasErrors)) + hasErrorsChanged = true; + }; + + vm.ResourceKey = invalidName; + Assume.That (vm.HasErrors, Is.True); + Assume.That (hasErrorsChanged, Is.True, "HasErrors did not change"); + Assume.That (errorsChanged, Is.True, "ErrorsChanged did not fire"); + hasErrorsChanged = errorsChanged = false; + + vm.DefineInApplicationSource = true; + provider.Verify (r => r.CheckNameErrorsAsync (target, It.IsAny<ResourceSource> (), invalidName), Times.AtLeast (2)); + Assert.That (vm.HasErrors, Is.False); + Assert.That (hasErrorsChanged, Is.True, "HasErrors did not change"); + Assert.That (errorsChanged, Is.True, "ErrorsChanged did not fire"); + } + + [Test] + public void DoesntErrorCheckBeforeSourceSet () + { + var target = new object(); + var property = new Mock<IPropertyInfo>(); + property.SetupGet (pi => pi.Type).Returns (typeof(string)); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (Sources); + provider.Setup (p => + p.SuggestResourceNameAsync (It.IsAny<IReadOnlyCollection<object>> (), It.IsAny<IPropertyInfo> ())) + .ReturnsAsync ("suggested"); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + provider.Verify (r => r.CheckNameErrorsAsync (target, null, It.IsAny<string>()), Times.Never); + } + + [Test] + public void NameErrorCleared () + { + const string error = "failed"; + const string invalidName = "test"; + var target = new object(); + var property = new Mock<IPropertyInfo>(); + property.SetupGet (pi => pi.Type).Returns (typeof(string)); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (Sources); + provider.Setup (p => p.CheckNameErrorsAsync (target, It.IsAny<ResourceSource> (), invalidName)) + .ReturnsAsync (new ResourceCreateError (error, false)); + provider.Setup (p => p.CheckNameErrorsAsync (target, It.IsAny<ResourceSource> (), It.IsNotIn (invalidName))) + .ReturnsAsync ((ResourceCreateError)null); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + bool errorsChanged = false; + vm.ErrorsChanged += (sender, args) => { + if (args.PropertyName == nameof(CreateResourceViewModel.ResourceKey)) + errorsChanged = true; + }; + + bool hasErrorsChanged = false; + vm.PropertyChanged += (sender, args) => { + if (args.PropertyName == nameof(CreateResourceViewModel.HasErrors)) + hasErrorsChanged = true; + }; + + vm.ResourceKey = invalidName; + Assume.That (vm.HasErrors, Is.True); + Assume.That (hasErrorsChanged, Is.True, "HasErrors did not change"); + Assume.That (errorsChanged, Is.True, "ErrorsChanged did not fire"); + Assume.That (vm.GetErrors (nameof(CreateResourceViewModel.ResourceKey)), Contains.Item (error)); + errorsChanged = false; + hasErrorsChanged = false; + + vm.ResourceKey = "validName"; + Assert.That (vm.HasErrors, Is.False); + Assert.That (hasErrorsChanged, Is.True, "HasErrors did not change"); + Assert.That (errorsChanged, Is.True, "ErrorsChanged did not fire"); + Assert.That (vm.GetErrors (nameof(CreateResourceViewModel.ResourceKey)), Does.Not.Contain (error)); + } + + [Test] + public void SuggestedName () + { + var target = new object(); + var property = new Mock<IPropertyInfo>(); + property.SetupGet (pi => pi.Type).Returns (typeof(string)); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (Sources); + + var tcs = new TaskCompletionSource<string> (); + provider.Setup (p => p.SuggestResourceNameAsync (It.IsAny<IReadOnlyList<object>> (), property.Object)) + .Returns (tcs.Task); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + Assume.That (vm.ResourceKey, Is.Null); + + bool changed = false; + vm.PropertyChanged += (o, e) => { + if (e.PropertyName == nameof(CreateResourceViewModel.ResourceKey)) + changed = true; + }; + + const string suggested = "suggested"; + tcs.SetResult (suggested); + Assert.That (changed, Is.True, "ResourceKey did not change"); + Assert.That (vm.ResourceKey, Is.EqualTo (suggested)); + } + + [Test] + public void SuggestedNameAfterChanged () + { + var target = new object(); + var property = new Mock<IPropertyInfo>(); + property.SetupGet (pi => pi.Type).Returns (typeof(string)); + var provider = new Mock<IResourceProvider>(); + provider.Setup (p => p.GetResourceSourcesAsync (target, property.Object)).ReturnsAsync (Sources); + + var tcs = new TaskCompletionSource<string> (); + provider.Setup (p => p.SuggestResourceNameAsync (It.IsAny<IReadOnlyList<object>> (), property.Object)) + .Returns (tcs.Task); + + var vm = new CreateResourceViewModel (provider.Object, new[] { target }, property.Object); + Assume.That (vm.ResourceKey, Is.Null); + + const string userKey = "Test"; + vm.ResourceKey = userKey; + + bool changed = false; + vm.PropertyChanged += (o, e) => { + if (e.PropertyName == nameof(CreateResourceViewModel.ResourceKey)) + changed = true; + }; + + tcs.SetResult ("suggested"); + Assert.That (changed, Is.False, "ResourceKey changed when suggested completed"); + Assert.That (vm.ResourceKey, Is.EqualTo (userKey), "ResourceKey changed from user set key after suggested"); + } + + private static readonly ResourceSource[] Sources = new[] { + new ResourceSource ("app", ResourceSourceType.Application), + new ResourceSource ("Resources.xaml", ResourceSourceType.ResourceDictionary), + new ResourceSource ("MyStyles.xaml", ResourceSourceType.ResourceDictionary), + new ResourceSource ("Page", ResourceSourceType.Document), + new ResourceSource ("Grid", ResourceSourceType.Document), + new ResourceSource ("system", ResourceSourceType.System), + }; + } +} diff --git a/Xamarin.PropertyEditing.Tests/PropertyViewModelTests.cs b/Xamarin.PropertyEditing.Tests/PropertyViewModelTests.cs index e1300a8..04a23af 100644 --- a/Xamarin.PropertyEditing.Tests/PropertyViewModelTests.cs +++ b/Xamarin.PropertyEditing.Tests/PropertyViewModelTests.cs @@ -1052,6 +1052,108 @@ namespace Xamarin.PropertyEditing.Tests Assert.That (vm.NavigateToValueSourceCommand.CanExecute (null), Is.True, "Navigate not enabled once value source became valid"); } + [Test] + public void CanCreateResource () + { + var mockProperty = GetPropertyMock (); + mockProperty.SetupGet (pi => pi.ValueSources).Returns (ValueSources.Default | ValueSources.Local | ValueSources.Resource); + var editor = new MockObjectEditor (mockProperty.Object); + + var resourceProvider = new Mock<IResourceProvider> (); + resourceProvider.SetupGet (rp => rp.CanCreateResources).Returns (true); + + var vm = GetViewModel (mockProperty.Object, new[] { editor }); + vm.ResourceProvider = resourceProvider.Object; + Assert.That (vm.CanCreateResources, Is.True); + } + + [Test] + public async Task CanRequestCreateResource () + { + var value = GetNonDefaultRandomTestValue (); + + var mockProperty = GetPropertyMock (); + mockProperty.SetupGet (pi => pi.ValueSources).Returns (ValueSources.Default | ValueSources.Local | ValueSources.Resource); + var editor = new MockObjectEditor (mockProperty.Object); + await editor.SetValueAsync (mockProperty.Object, new ValueInfo<TValue> { + Source = ValueSource.Local, + Value = value + }); + + var resourceProvider = new Mock<IResourceProvider> (); + resourceProvider.SetupGet (rp => rp.CanCreateResources).Returns (true); + + var vm = GetViewModel (mockProperty.Object, new[] { editor }); + vm.ResourceProvider = resourceProvider.Object; + Assert.That (vm.RequestCreateResourceCommand.CanExecute (null), Is.True, "Can't create resources"); + } + + [Test] + public async Task CanRequestCreateResourceMultipleValues () + { + var value = GetNonDefaultRandomTestValue (); + var value2 = GetRandomTestValue (notValue: value); + + var mockProperty = GetPropertyMock (); + mockProperty.SetupGet (pi => pi.ValueSources).Returns (ValueSources.Default | ValueSources.Local | ValueSources.Resource); + var editor = new MockObjectEditor (mockProperty.Object); + await editor.SetValueAsync (mockProperty.Object, new ValueInfo<TValue> { + Source = ValueSource.Local, + Value = value + }); + var editor2 = new MockObjectEditor (mockProperty.Object); + await editor2.SetValueAsync (mockProperty.Object, new ValueInfo<TValue> { + Source = ValueSource.Local, + Value = value2 + }); + + var resourceProvider = new Mock<IResourceProvider> (); + resourceProvider.SetupGet (rp => rp.CanCreateResources).Returns (true); + + var vm = GetViewModel (mockProperty.Object, new[] { editor }); + vm.ResourceProvider = resourceProvider.Object; + Assume.That (vm.RequestCreateResourceCommand.CanExecute (null), Is.True, "Can't create resources initially"); + + bool changed = false; + vm.RequestCreateResourceCommand.CanExecuteChanged += (sender, args) => { + changed = true; + }; + + vm.Editors.Add (editor2); + Assume.That (vm.MultipleValues, Is.True); + Assert.That (changed, Is.True, "RequestCreateResourceCommand didn't change can execute"); + Assert.That (vm.RequestCreateResourceCommand.CanExecute (null), Is.False, "CanCreateResources was true after differing value added"); + } + + [Test] + public async Task CreateResource () + { + var value = GetNonDefaultRandomTestValue (); + + var mockProperty = GetPropertyMock (); + mockProperty.SetupGet (pi => pi.ValueSources).Returns (ValueSources.Default | ValueSources.Local | ValueSources.Resource); + var editor = new MockObjectEditor (mockProperty.Object); + await editor.SetValueAsync (mockProperty.Object, new ValueInfo<TValue> { + Source = ValueSource.Local, + Value = value + }); + + var resourceProvider = new Mock<IResourceProvider> (); + resourceProvider.SetupGet (rp => rp.CanCreateResources).Returns (true); + + var vm = GetViewModel (mockProperty.Object, new[] { editor }); + vm.ResourceProvider = resourceProvider.Object; + Assume.That (vm.RequestCreateResourceCommand.CanExecute (null), Is.True, "Can't create resources"); + + bool requested = false; + vm.CreateResourceRequested += (o, e) => { + requested = true; + }; + + vm.RequestCreateResourceCommand.Execute (null); + Assert.That (requested, Is.True, "CreateResourceRequested did not fire"); + } + protected TViewModel GetViewModel (IPropertyInfo property, IObjectEditor editor) { return GetViewModel (property, new[] { editor }); @@ -1103,6 +1205,7 @@ namespace Xamarin.PropertyEditing.Tests mock.SetupGet (pi => pi.Type).Returns (typeof(TValueReal)); mock.SetupGet (pi => pi.Name).Returns (name); mock.SetupGet (pi => pi.Category).Returns (category); + mock.SetupGet (pi => pi.CanWrite).Returns (true); AugmentPropertyMock (mock); return mock; diff --git a/Xamarin.PropertyEditing.Tests/Xamarin.PropertyEditing.Tests.csproj b/Xamarin.PropertyEditing.Tests/Xamarin.PropertyEditing.Tests.csproj index 86c7c63..10e1eda 100644 --- a/Xamarin.PropertyEditing.Tests/Xamarin.PropertyEditing.Tests.csproj +++ b/Xamarin.PropertyEditing.Tests/Xamarin.PropertyEditing.Tests.csproj @@ -64,6 +64,7 @@ <Compile Include="BrushPropertyViewModelTests.cs" /> <Compile Include="BytePropertyViewModelTests.cs" /> <Compile Include="CollectionPropertyViewModelTests.cs" /> + <Compile Include="CreateResourceViewModelTests.cs" /> <Compile Include="MaterialDesignColorViewModelTests.cs" /> <Compile Include="CombinablePredefinedViewModelTests.cs" /> <Compile Include="MockControls\MockResourceProvider.cs" /> diff --git a/Xamarin.PropertyEditing.Windows/CreateResourceWindow.xaml b/Xamarin.PropertyEditing.Windows/CreateResourceWindow.xaml new file mode 100644 index 0000000..d12a118 --- /dev/null +++ b/Xamarin.PropertyEditing.Windows/CreateResourceWindow.xaml @@ -0,0 +1,81 @@ +<local:WindowEx x:Class="Xamarin.PropertyEditing.Windows.CreateResourceWindow" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="clr-namespace:Xamarin.PropertyEditing.Windows" + xmlns:prop="clr-namespace:Xamarin.PropertyEditing.Properties;assembly=Xamarin.PropertyEditing" + mc:Ignorable="d" x:ClassModifier="internal" + Background="{DynamicResource DialogBackgroundBrush}" Foreground="{DynamicResource DialogForegroundBrush}" + Height="270" Width="500" ResizeMode="NoResize" ShowMaximize="False" ShowIcon="False" ShowMinimize="False" + WindowStartupLocation="CenterOwner"> + <local:WindowEx.Title> + <Binding StringFormat="{x:Static prop:Resources.CreateResourceTitle}" Path="Property.TypeName" Mode="OneTime" /> + </local:WindowEx.Title> + <local:WindowEx.Resources> + <Style TargetType="RadioButton"> + <Setter Property="Margin" Value="24,4,0,0" /> + <Setter Property="Foreground" Value="{DynamicResource DialogForegroundBrush}" /> + <Setter Property="FocusVisualStyle" Value="{DynamicResource GenericVisualFocusStyle}" /> + <Setter Property="VerticalAlignment" Value="Center" /> + <Style.Triggers> + <Trigger Property="IsEnabled" Value="False"> + <Setter Property="Foreground" Value="#FFA2A4A5" /> + </Trigger> + </Style.Triggers> + </Style> + </local:WindowEx.Resources> + <Grid Margin="12"> + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + </Grid.RowDefinitions> + + <GroupBox Grid.Row="0" Header="{x:Static prop:Resources.ResourceNameLabel}" Margin="0,4,0,0" BorderThickness="0"> + <StackPanel> + <RadioButton HorizontalContentAlignment="Stretch" IsChecked="{Binding IsKeyed,Mode=TwoWay}"> + <local:TextBoxEx x:Name="resourceKey" Text="{Binding ResourceKey,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Style="{DynamicResource ValidationTextBox}" /> + </RadioButton> + <RadioButton IsEnabled="{Binding CanApplyToAll,Mode=OneTime}" IsChecked="{Binding IsAppliedToAll,Mode=TwoWay}">Apply to all</RadioButton> + </StackPanel> + </GroupBox> + + <GroupBox Grid.Row="1" Header="{x:Static prop:Resources.DefineIn}" Margin="0,4,0,0" BorderThickness="0"> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="27" /> + <RowDefinition Height="27" /> + <RowDefinition Height="27" /> + </Grid.RowDefinitions> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + + <RadioButton Grid.Column="0" Grid.Row="0" Content="{x:Static prop:Resources.Application}" IsChecked="{Binding DefineInApplication,Mode=TwoWay}" /> + <RadioButton Grid.Column="0" Grid.Row="1" Content="{x:Static prop:Resources.ThisDocument}" IsEnabled="{Binding HasDocumentSources}" IsChecked="{Binding DefineInDocument,Mode=TwoWay}" /> + <RadioButton Grid.Column="0" Grid.Row="2" Content="{x:Static prop:Resources.ResourceDictionary}" IsEnabled="{Binding HasApplicationSources}" IsChecked="{Binding DefineInApplicationSource,Mode=TwoWay}" /> + + <ComboBox Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Width="160" Margin="25,4,25,0" IsEnabled="{Binding DefineInDocument}" ItemsSource="{Binding DocumentSources}" SelectedItem="{Binding SelectedDocumentSource,Mode=TwoWay}" DisplayMemberPath="Name" /> + <ComboBox Grid.Column="1" Grid.Row="2" VerticalAlignment="Center" Width="160" Margin="25,4,25,0" IsEnabled="{Binding DefineInApplicationSource}" ItemsSource="{Binding ApplicationSources}" SelectedItem="{Binding SelectedApplicationSource,Mode=TwoWay}" DisplayMemberPath="Name" /> + </Grid> + </GroupBox> + + <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,4,0,0"> + <Button Name="ok" MinHeight="23" MinWidth="75" Content="{x:Static prop:Resources.OK}" IsDefault="True" Command="{Binding CreateResourceCommand,Mode=OneTime}" Click="OnOkClicked" /> + <Button MinHeight="23" MinWidth="75" Margin="4,0,0,0" Content="{x:Static prop:Resources.Cancel}" IsCancel="True" Click="OnCancelClicked" /> + </StackPanel> + + <Border Background="{DynamicResource DialogBackgroundBrush}" Grid.Row="0" Grid.RowSpan="2"> + <Border.Visibility> + <Binding Path="HasFatalError"> + <Binding.Converter> + <BooleanToVisibilityConverter /> + </Binding.Converter> + </Binding> + </Border.Visibility> + <TextBlock Text="{Binding FatalError}" HorizontalAlignment="Center" VerticalAlignment="Center" /> + </Border> + </Grid> +</local:WindowEx> diff --git a/Xamarin.PropertyEditing.Windows/CreateResourceWindow.xaml.cs b/Xamarin.PropertyEditing.Windows/CreateResourceWindow.xaml.cs new file mode 100644 index 0000000..0f6aa6a --- /dev/null +++ b/Xamarin.PropertyEditing.Windows/CreateResourceWindow.xaml.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Windows; +using Xamarin.PropertyEditing.ViewModels; + +namespace Xamarin.PropertyEditing.Windows +{ + internal partial class CreateResourceWindow + : WindowEx + { + public CreateResourceWindow (IEnumerable<ResourceDictionary> merged, IResourceProvider provider, IEnumerable<object> targets, IPropertyInfo property) + { + Resources.MergedDictionaries.AddItems (merged); + DataContext = new CreateResourceViewModel (provider, targets, property); + InitializeComponent (); + SetupResourceKey (); + } + + private async void SetupResourceKey() + { + await ((CreateResourceViewModel) DataContext).LoadingTask; + this.resourceKey.SelectAll(); + this.resourceKey.Focus (); + } + + private void OnOkClicked (object sender, RoutedEventArgs e) + { + DialogResult = true; + } + + private void OnCancelClicked (object sender, RoutedEventArgs e) + { + DialogResult = false; + } + + internal static Tuple<ResourceSource, string> CreateResource (FrameworkElement owner, IResourceProvider provider, IEnumerable<object> targets, IPropertyInfo property) + { + Window ownerWindow = Window.GetWindow (owner); + var window = new CreateResourceWindow (owner.Resources.MergedDictionaries, provider, targets, property) { + Owner = ownerWindow + }; + window.Resources.MergedDictionaries.AddItems (owner.Resources.MergedDictionaries); + bool? result = window.ShowDialog(); + + var vm = (CreateResourceViewModel)window.DataContext; + if (result.HasValue && result.Value) { + return new Tuple<ResourceSource, string> (vm.SelectedResourceSource, vm.ResourceKey); + } else { + return new Tuple<ResourceSource, string> (null, null); + } + } + } +} diff --git a/Xamarin.PropertyEditing.Windows/PropertyButton.cs b/Xamarin.PropertyEditing.Windows/PropertyButton.cs index c32cbf7..f69bc2c 100644 --- a/Xamarin.PropertyEditing.Windows/PropertyButton.cs +++ b/Xamarin.PropertyEditing.Windows/PropertyButton.cs @@ -99,12 +99,16 @@ namespace Xamarin.PropertyEditing.Windows private void OnDataContextChanged (object sender, DependencyPropertyChangedEventArgs e) { - if (e.OldValue is PropertyViewModel pvm) + if (e.OldValue is PropertyViewModel pvm) { pvm.ResourceRequested -= OnResourceRequested; + pvm.CreateResourceRequested -= OnCreateResourceRequested; + } this.vm = e.NewValue as PropertyViewModel; - if (this.vm != null) + if (this.vm != null) { this.vm.ResourceRequested += OnResourceRequested; + this.vm.CreateResourceRequested += OnCreateResourceRequested; + } } private void OnValueSourceChanged (ValueSource source) @@ -140,9 +144,19 @@ namespace Xamarin.PropertyEditing.Windows private void OnResourceRequested (object sender, ResourceRequestedEventArgs e) { - var panel = this.FindParent<PropertyEditorPanel> (); - var vm = ((PropertyViewModel)DataContext); - e.Resource = ResourceSelectorWindow.RequestResource (panel, vm.ResourceProvider, vm.Editors.Select (ed => ed.Target), vm.Property, e.Resource); + var panel = this.FindPropertiesHost(); + var pvm = (PropertyViewModel) DataContext; + e.Resource = ResourceSelectorWindow.RequestResource (panel, pvm.ResourceProvider, pvm.Editors.Select (ed => ed.Target), pvm.Property, e.Resource); + } + + private void OnCreateResourceRequested (object sender, CreateResourceRequestedEventArgs e) + { + var panel = this.FindPropertiesHost(); + var pvm = (PropertyViewModel) DataContext; + + var result = CreateResourceWindow.CreateResource (panel, pvm.ResourceProvider, pvm.Editors.Select (oe => oe.Target), pvm.Property); + e.Source = result.Item1; + e.Name = result.Item2; } private void OnCustomExpression (object sender, RoutedEventArgs e) diff --git a/Xamarin.PropertyEditing.Windows/ResourceSelectorWindow.xaml.cs b/Xamarin.PropertyEditing.Windows/ResourceSelectorWindow.xaml.cs index f26e188..7744761 100644 --- a/Xamarin.PropertyEditing.Windows/ResourceSelectorWindow.xaml.cs +++ b/Xamarin.PropertyEditing.Windows/ResourceSelectorWindow.xaml.cs @@ -18,7 +18,7 @@ namespace Xamarin.PropertyEditing.Windows InitializeComponent (); } - internal static Resource RequestResource (PropertyEditorPanel owner, IResourceProvider provider, IEnumerable<object> targets, IPropertyInfo property, Resource currentValue) + internal static Resource RequestResource (FrameworkElement owner, IResourceProvider provider, IEnumerable<object> targets, IPropertyInfo property, Resource currentValue) { Window hostWindow = Window.GetWindow (owner); diff --git a/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml b/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml index 4497fe9..5f40012 100644 --- a/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml +++ b/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml @@ -411,11 +411,8 @@ <MenuItem Header="{x:Static prop:Resources.ConvertToLocalValue}" Icon="{StaticResource LiteralMarker}" Command="{Binding ConvertToLocalValueCommand,Mode=OneTime}" /> <Separator Visibility="{Binding SupportsResources,Mode=OneTime,Converter={StaticResource BoolToVisibilityConverter}}" /> <MenuItem Header="{x:Static prop:Resources.ResourceEllipsis}" Command="{Binding RequestResourceCommand,Mode=OneTime}" Icon="{StaticResource ResourceMarker}" Visibility="{Binding SupportsResources,Mode=OneTime,Converter={StaticResource BoolToVisibilityConverter}}" /> - <!--<MenuItem Header="{x:Static prop:Resources.LocalResource}" /> - <MenuItem Header="{x:Static prop:Resources.SystemResource}" /> - <MenuItem Header="{x:Static prop:Resources.EditResourceEllipse}" /> - <MenuItem Header="{x:Static prop:Resources.ConvertToNewResourceEllipse}" /> - <Separator /> + <MenuItem Header="{x:Static prop:Resources.ConvertToNewResourceEllipsis}" Command="{Binding RequestCreateResourceCommand}" Icon="{StaticResource ResourceMarker}" Visibility="{Binding CanCreateResources,Converter={StaticResource BoolToVisibilityConverter}}" /> + <!--<Separator /> <MenuItem Header="{x:Static prop:Resources.CreateDataBindingEllipse}" /> <MenuItem Header="{x:Static prop:Resources.TemplateBinding}" />!--> <Separator Visibility="{Binding SupportsValueSourceNavigation,Mode=OneTime,Converter={StaticResource BoolToVisibilityConverter}}" /> @@ -1935,6 +1932,21 @@ </Style.Triggers> </Style> + <Style x:Key="ValidationTextBox" TargetType="local:TextBoxEx" BasedOn="{StaticResource {x:Type local:TextBoxEx}}"> + <Setter Property="Validation.ErrorTemplate"> + <Setter.Value> + <ControlTemplate> + <DockPanel> + <AdornedElementPlaceholder Name="adorned" DockPanel.Dock="Top" /> + <Border DockPanel.Dock="Bottom" Background="{DynamicResource ToolTipBackgroundBrush}" BorderThickness="1" BorderBrush="{DynamicResource ToolTipBorderBrush}"> + <ContentPresenter Margin="7,4,7,4" TextElement.Foreground="{DynamicResource ToolTipForegroundBrush}" Content="{Binding ElementName=adorned,Path=AdornedElement.(Validation.Errors)/ErrorContent}" /> + </Border> + </DockPanel> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + <local:NumericTemplateSelector x:Key="NumericTemplateSelector"> <local:NumericTemplateSelector.FloatingTemplate> <DataTemplate DataType="vm:FloatingPropertyViewModel"> diff --git a/Xamarin.PropertyEditing.Windows/Themes/VS.Dark.xaml b/Xamarin.PropertyEditing.Windows/Themes/VS.Dark.xaml index 5c54e51..e59794c 100644 --- a/Xamarin.PropertyEditing.Windows/Themes/VS.Dark.xaml +++ b/Xamarin.PropertyEditing.Windows/Themes/VS.Dark.xaml @@ -76,6 +76,10 @@ <SolidColorBrush x:Key="PopupForegroundBrush">#FFF1F1F1</SolidColorBrush> <SolidColorBrush x:Key="PopupBorderBrush">#FF333337</SolidColorBrush> + <SolidColorBrush x:Key="ToolTipForegroundBrush">#FF000000</SolidColorBrush> + <SolidColorBrush x:Key="ToolTipBorderBrush">#FF000000</SolidColorBrush> + <SolidColorBrush x:Key="ToolTipBackgroundBrush">#FFFFFFFF</SolidColorBrush> + <SolidColorBrush x:Key="ThicknessIconBackgroundBrush">#292929</SolidColorBrush> <SolidColorBrush x:Key="ThicknessIconBorderBrush">#292929</SolidColorBrush> @@ -110,7 +114,7 @@ <SolidColorBrush x:Key="ComboBoxButtonPressedSeparatorBrush">#FF007ACC</SolidColorBrush> <SolidColorBrush x:Key="ComboBoxPopupBackgroundBrush">#FF1B1B1C</SolidColorBrush> <SolidColorBrush x:Key="ComboBoxPopupBorderBrush">#FF333337</SolidColorBrush> - + <SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Fill" Color="Transparent"/> <SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Stroke" Color="#F1F1F1"/> <SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Checked.Fill" Color="#F1F1F1"/> diff --git a/Xamarin.PropertyEditing.Windows/Themes/VS.Light.xaml b/Xamarin.PropertyEditing.Windows/Themes/VS.Light.xaml index 09811c7..88368aa 100644 --- a/Xamarin.PropertyEditing.Windows/Themes/VS.Light.xaml +++ b/Xamarin.PropertyEditing.Windows/Themes/VS.Light.xaml @@ -77,6 +77,10 @@ <SolidColorBrush x:Key="PopupForegroundBrush">#FF1E1E1E</SolidColorBrush> <SolidColorBrush x:Key="PopupBorderBrush">#FFCCCEDB</SolidColorBrush> + <SolidColorBrush x:Key="ToolTipForegroundBrush">#FF000000</SolidColorBrush> + <SolidColorBrush x:Key="ToolTipBorderBrush">#FF000000</SolidColorBrush> + <SolidColorBrush x:Key="ToolTipBackgroundBrush">#FFFFFFFF</SolidColorBrush> + <SolidColorBrush x:Key="ThicknessIconBackgroundBrush">#EEEEF2</SolidColorBrush> <SolidColorBrush x:Key="ThicknessIconBorderBrush">#EEEEF2</SolidColorBrush> diff --git a/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj b/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj index 659634c..cb1a9f9 100644 --- a/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj +++ b/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj @@ -80,6 +80,9 @@ <Compile Include="ColorEditorControlBase.cs" /> <Compile Include="ColorHelper.cs" /> <Compile Include="CommonColorToColorConverter.cs" /> + <Compile Include="CreateResourceWindow.xaml.cs"> + <DependentUpon>CreateResourceWindow.xaml</DependentUpon> + </Compile> <Compile Include="EntryPopup.cs" /> <Compile Include="CurrentColorEditorControl.cs" /> <Compile Include="DoubleToPercentageConverter.cs" /> @@ -134,6 +137,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="CreateResourceWindow.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="ResourceSelectorWindow.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> diff --git a/Xamarin.PropertyEditing/Properties/Resources.Designer.cs b/Xamarin.PropertyEditing/Properties/Resources.Designer.cs index f065311..a53e3c1 100644 --- a/Xamarin.PropertyEditing/Properties/Resources.Designer.cs +++ b/Xamarin.PropertyEditing/Properties/Resources.Designer.cs @@ -10,35 +10,48 @@ namespace Xamarin.PropertyEditing.Properties { using System; - using System.Reflection; - - - [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [System.Diagnostics.DebuggerNonUserCodeAttribute()] - [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Resources { - - private static System.Resources.ResourceManager resourceMan; - - private static System.Globalization.CultureInfo resourceCulture; - - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } - - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - public static System.Resources.ResourceManager ResourceManager { + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { get { - if (object.Equals(null, resourceMan)) { - System.Resources.ResourceManager temp = new System.Resources.ResourceManager("Xamarin.PropertyEditing.Properties.Resources", typeof(Resources).Assembly); + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Xamarin.PropertyEditing.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - public static System.Globalization.CultureInfo Culture { + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } @@ -46,61 +59,124 @@ namespace Xamarin.PropertyEditing.Properties { resourceCulture = value; } } - + + /// <summary> + /// Looks up a localized string similar to Alpha. + /// </summary> public static string Alpha { get { return ResourceManager.GetString("Alpha", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to A. + /// </summary> public static string AlphaInitial { get { return ResourceManager.GetString("AlphaInitial", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Application. + /// </summary> + public static string Application { + get { + return ResourceManager.GetString("Application", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Apply to all. + /// </summary> + public static string ApplyToAll { + get { + return ResourceManager.GetString("ApplyToAll", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Binding. + /// </summary> + public static string Binding { + get { + return ResourceManager.GetString("Binding", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Black. + /// </summary> public static string Black { get { return ResourceManager.GetString("Black", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to K. + /// </summary> public static string BlackInitial { get { return ResourceManager.GetString("BlackInitial", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Blue. + /// </summary> public static string Blue { get { return ResourceManager.GetString("Blue", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to B. + /// </summary> public static string BlueInitial { get { return ResourceManager.GetString("BlueInitial", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Brightness. + /// </summary> public static string Brightness { get { return ResourceManager.GetString("Brightness", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to B. + /// </summary> public static string BrightnessInitial { get { return ResourceManager.GetString("BrightnessInitial", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Cancel. + /// </summary> + public static string Cancel { + get { + return ResourceManager.GetString("Cancel", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to CMYK. + /// </summary> public static string CMYK { get { return ResourceManager.GetString("CMYK", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to Collection Editor: {0}. /// </summary> @@ -109,7 +185,7 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("CollectionEditorTitle", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to (Collection). /// </summary> @@ -118,7 +194,7 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("CollectionValue", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to Editor. /// </summary> @@ -127,7 +203,7 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("ColorEditorTabLabel", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to Color space. /// </summary> @@ -136,43 +212,106 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("ColorSpace", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Convert to Local Value. + /// </summary> + public static string ConvertToLocalValue { + get { + return ResourceManager.GetString("ConvertToLocalValue", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Convert to new resource…. + /// </summary> + public static string ConvertToNewResourceEllipsis { + get { + return ResourceManager.GetString("ConvertToNewResourceEllipsis", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Create {0} Resource. + /// </summary> + public static string CreateResourceTitle { + get { + return ResourceManager.GetString("CreateResourceTitle", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Current color. + /// </summary> public static string CurrentColor { get { return ResourceManager.GetString("CurrentColor", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Custom expression. + /// </summary> + public static string CustomExpression { + get { + return ResourceManager.GetString("CustomExpression", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Custom Expression…. + /// </summary> + public static string CustomExpressionEllipsis { + get { + return ResourceManager.GetString("CustomExpressionEllipsis", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Cyan. + /// </summary> public static string Cyan { get { return ResourceManager.GetString("Cyan", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to C. + /// </summary> public static string CyanInitial { get { return ResourceManager.GetString("CyanInitial", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Cyan / Magenta / Yellow / Black. + /// </summary> public static string CyanMagentaYellowBlack { get { return ResourceManager.GetString("CyanMagentaYellowBlack", resourceCulture); } } - - public static string ConvertToLocalValue { + + /// <summary> + /// Looks up a localized string similar to Default. + /// </summary> + public static string Default { get { - return ResourceManager.GetString("ConvertToLocalValue", resourceCulture); + return ResourceManager.GetString("Default", resourceCulture); } } - - public static string CustomExpressionEllipsis { + + /// <summary> + /// Looks up a localized string similar to Define in. + /// </summary> + public static string DefineIn { get { - return ResourceManager.GetString("CustomExpressionEllipsis", resourceCulture); + return ResourceManager.GetString("DefineIn", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to …. /// </summary> @@ -181,7 +320,7 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("Ellipsis", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to Event handlers for the selected element. /// </summary> @@ -190,13 +329,25 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("EventHandlersSelectedElement", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Events. + /// </summary> public static string Events { get { return ResourceManager.GetString("Events", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Something went wrong. + /// </summary> + public static string GenericErrorMessage { + get { + return ResourceManager.GetString("GenericErrorMessage", resourceCulture); + } + } + /// <summary> /// Looks up a localized string similar to Go to Source. /// </summary> @@ -205,7 +356,7 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("GoToSource", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to Green. /// </summary> @@ -214,61 +365,97 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("Green", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to G. + /// </summary> public static string GreenInitial { get { return ResourceManager.GetString("GreenInitial", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Hex value. + /// </summary> public static string HexValue { get { return ResourceManager.GetString("HexValue", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to HLS. + /// </summary> public static string HLS { get { return ResourceManager.GetString("HLS", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to HSB. + /// </summary> public static string HSB { get { return ResourceManager.GetString("HSB", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Hue. + /// </summary> public static string Hue { get { return ResourceManager.GetString("Hue", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to H. + /// </summary> public static string HueInitial { get { return ResourceManager.GetString("HueInitial", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Hue / Lightness / Saturation. + /// </summary> public static string HueLightnessSaturation { get { return ResourceManager.GetString("HueLightnessSaturation", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Hue / Saturation / Brightness. + /// </summary> public static string HueSaturationBrightness { get { return ResourceManager.GetString("HueSaturationBrightness", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Inherited. + /// </summary> + public static string Inherited { + get { + return ResourceManager.GetString("Inherited", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Initial color. + /// </summary> public static string InitialColor { get { return ResourceManager.GetString("InitialColor", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to {0} is an Invalid Value. /// </summary> @@ -277,7 +464,7 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("InvalidValue", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to Items. /// </summary> @@ -286,7 +473,7 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("Items", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to Last color. /// </summary> @@ -295,157 +482,241 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("LastColor", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Lightness. + /// </summary> public static string Lightness { get { return ResourceManager.GetString("Lightness", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to L. + /// </summary> public static string LightnessInitial { get { return ResourceManager.GetString("LightnessInitial", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to Local. + /// </summary> + public static string Local { + get { + return ResourceManager.GetString("Local", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Magenta. + /// </summary> public static string Magenta { get { return ResourceManager.GetString("Magenta", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to M. + /// </summary> public static string MagentaInitial { get { return ResourceManager.GetString("MagentaInitial", resourceCulture); } } - - public static string MultipleObjectsSelected { + + /// <summary> + /// Looks up a localized string similar to Amber. + /// </summary> + public static string MaterialColorAmber { get { - return ResourceManager.GetString("MultipleObjectsSelected", resourceCulture); + return ResourceManager.GetString("MaterialColorAmber", resourceCulture); } } - - public static string MultipleTypesSelected { + + /// <summary> + /// Looks up a localized string similar to Black and White. + /// </summary> + public static string MaterialColorBlackAndWhite { get { - return ResourceManager.GetString("MultipleTypesSelected", resourceCulture); + return ResourceManager.GetString("MaterialColorBlackAndWhite", resourceCulture); } } - - public static string Name { + + /// <summary> + /// Looks up a localized string similar to Blue. + /// </summary> + public static string MaterialColorBlue { get { - return ResourceManager.GetString("Name", resourceCulture); + return ResourceManager.GetString("MaterialColorBlue", resourceCulture); } } - - public static string NoName { + + /// <summary> + /// Looks up a localized string similar to Blue Grey. + /// </summary> + public static string MaterialColorBlueGrey { get { - return ResourceManager.GetString("NoName", resourceCulture); + return ResourceManager.GetString("MaterialColorBlueGrey", resourceCulture); } } - - public static string Properties { + + /// <summary> + /// Looks up a localized string similar to Brown. + /// </summary> + public static string MaterialColorBrown { get { - return ResourceManager.GetString("Properties", resourceCulture); + return ResourceManager.GetString("MaterialColorBrown", resourceCulture); } } - - public static string PropertiesSelectedElement { + + /// <summary> + /// Looks up a localized string similar to Cyan. + /// </summary> + public static string MaterialColorCyan { get { - return ResourceManager.GetString("PropertiesSelectedElement", resourceCulture); + return ResourceManager.GetString("MaterialColorCyan", resourceCulture); } } - - public static string Red { + + /// <summary> + /// Looks up a localized string similar to Deep Orange. + /// </summary> + public static string MaterialColorDeepOrange { get { - return ResourceManager.GetString("Red", resourceCulture); + return ResourceManager.GetString("MaterialColorDeepOrange", resourceCulture); } } - - public static string RedGreenBlue { + + /// <summary> + /// Looks up a localized string similar to Deep Purple. + /// </summary> + public static string MaterialColorDeepPurple { get { - return ResourceManager.GetString("RedGreenBlue", resourceCulture); + return ResourceManager.GetString("MaterialColorDeepPurple", resourceCulture); } } - - public static string RedInitial { + + /// <summary> + /// Looks up a localized string similar to Green. + /// </summary> + public static string MaterialColorGreen { get { - return ResourceManager.GetString("RedInitial", resourceCulture); + return ResourceManager.GetString("MaterialColorGreen", resourceCulture); } } - - public static string RGB { + + /// <summary> + /// Looks up a localized string similar to Grey. + /// </summary> + public static string MaterialColorGrey { get { - return ResourceManager.GetString("RGB", resourceCulture); + return ResourceManager.GetString("MaterialColorGrey", resourceCulture); } } - - public static string Saturation { + + /// <summary> + /// Looks up a localized string similar to Indigo. + /// </summary> + public static string MaterialColorIndigo { get { - return ResourceManager.GetString("Saturation", resourceCulture); + return ResourceManager.GetString("MaterialColorIndigo", resourceCulture); } } - - public static string SaturationInitial { + + /// <summary> + /// Looks up a localized string similar to Light Blue. + /// </summary> + public static string MaterialColorLightBlue { get { - return ResourceManager.GetString("SaturationInitial", resourceCulture); + return ResourceManager.GetString("MaterialColorLightBlue", resourceCulture); } } - - public static string Reset { + + /// <summary> + /// Looks up a localized string similar to Light Green. + /// </summary> + public static string MaterialColorLightGreen { get { - return ResourceManager.GetString("Reset", resourceCulture); + return ResourceManager.GetString("MaterialColorLightGreen", resourceCulture); } } - - public static string Type { + + /// <summary> + /// Looks up a localized string similar to Lime. + /// </summary> + public static string MaterialColorLime { get { - return ResourceManager.GetString("Type", resourceCulture); + return ResourceManager.GetString("MaterialColorLime", resourceCulture); } } - - public static string ViewPropertiesOrEvents { + + /// <summary> + /// Looks up a localized string similar to Orange. + /// </summary> + public static string MaterialColorOrange { get { - return ResourceManager.GetString("ViewPropertiesOrEvents", resourceCulture); + return ResourceManager.GetString("MaterialColorOrange", resourceCulture); } } - - public static string Yellow { + + /// <summary> + /// Looks up a localized string similar to Pink. + /// </summary> + public static string MaterialColorPink { get { - return ResourceManager.GetString("Yellow", resourceCulture); + return ResourceManager.GetString("MaterialColorPink", resourceCulture); } } - - public static string YellowInitial { + + /// <summary> + /// Looks up a localized string similar to Purple. + /// </summary> + public static string MaterialColorPurple { get { - return ResourceManager.GetString("YellowInitial", resourceCulture); + return ResourceManager.GetString("MaterialColorPurple", resourceCulture); } } - - public static string NoBrush { + + /// <summary> + /// Looks up a localized string similar to Red. + /// </summary> + public static string MaterialColorRed { get { - return ResourceManager.GetString("NoBrush", resourceCulture); + return ResourceManager.GetString("MaterialColorRed", resourceCulture); } } - - public static string SolidBrush { + + /// <summary> + /// Looks up a localized string similar to Teal. + /// </summary> + public static string MaterialColorTeal { get { - return ResourceManager.GetString("SolidBrush", resourceCulture); + return ResourceManager.GetString("MaterialColorTeal", resourceCulture); } } - - public static string ResourceBrush { + + /// <summary> + /// Looks up a localized string similar to Yellow. + /// </summary> + public static string MaterialColorYellow { get { - return ResourceManager.GetString("ResourceBrush", resourceCulture); + return ResourceManager.GetString("MaterialColorYellow", resourceCulture); } } - - public static string Opacity { + + /// <summary> + /// Looks up a localized string similar to Material Design Colors. + /// </summary> + public static string MaterialDesignColorBrush { get { - return ResourceManager.GetString("Opacity", resourceCulture); + return ResourceManager.GetString("MaterialDesignColorBrush", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to Move item down. /// </summary> @@ -454,7 +725,7 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("MoveItemDown", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to Move item up. /// </summary> @@ -463,67 +734,88 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("MoveItemUp", resourceCulture); } } - - public static string ShowAdvancedProperties { - get { - return ResourceManager.GetString("ShowAdvancedProperties", resourceCulture); - } - } - - public static string Cancel { + + /// <summary> + /// Looks up a localized string similar to {0} objects selected. + /// </summary> + public static string MultipleObjectsSelected { get { - return ResourceManager.GetString("Cancel", resourceCulture); + return ResourceManager.GetString("MultipleObjectsSelected", resourceCulture); } } - - public static string OK { + + /// <summary> + /// Looks up a localized string similar to {0} types selected. + /// </summary> + public static string MultipleTypesSelected { get { - return ResourceManager.GetString("OK", resourceCulture); + return ResourceManager.GetString("MultipleTypesSelected", resourceCulture); } } - - public static string ShowAllAssemblies { + + /// <summary> + /// Looks up a localized string similar to Name. + /// </summary> + public static string Name { get { - return ResourceManager.GetString("ShowAllAssemblies", resourceCulture); + return ResourceManager.GetString("Name", resourceCulture); } } - - public static string SearchProperties { + + /// <summary> + /// Looks up a localized string similar to New. + /// </summary> + public static string New { get { - return ResourceManager.GetString("SearchProperties", resourceCulture); + return ResourceManager.GetString("New", resourceCulture); } } - - public static string New { + + /// <summary> + /// Looks up a localized string similar to No brush. + /// </summary> + public static string NoBrush { get { - return ResourceManager.GetString("New", resourceCulture); + return ResourceManager.GetString("NoBrush", resourceCulture); } } - - public static string SearchObjectsTitle { + + /// <summary> + /// Looks up a localized string similar to <No Name>. + /// </summary> + public static string NoName { get { - return ResourceManager.GetString("SearchObjectsTitle", resourceCulture); + return ResourceManager.GetString("NoName", resourceCulture); } } - - public static string SelectObjectTitle { + + /// <summary> + /// Looks up a localized string similar to No preview available. + /// </summary> + public static string NoPreviewAvailable { get { - return ResourceManager.GetString("SelectObjectTitle", resourceCulture); + return ResourceManager.GetString("NoPreviewAvailable", resourceCulture); } } - - public static string CustomExpression { + + /// <summary> + /// Looks up a localized string similar to OK. + /// </summary> + public static string OK { get { - return ResourceManager.GetString("CustomExpression", resourceCulture); + return ResourceManager.GetString("OK", resourceCulture); } } - - public static string SearchResourcesTitle { + + /// <summary> + /// Looks up a localized string similar to Opacity. + /// </summary> + public static string Opacity { get { - return ResourceManager.GetString("SearchResourcesTitle", resourceCulture); + return ResourceManager.GetString("Opacity", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to <Other type…>. /// </summary> @@ -532,37 +824,52 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("OtherTypeAction", resourceCulture); } } - - public static string SelectResourceTitle { + + /// <summary> + /// Looks up a localized string similar to Properties. + /// </summary> + public static string Properties { get { - return ResourceManager.GetString("SelectResourceTitle", resourceCulture); + return ResourceManager.GetString("Properties", resourceCulture); } } - - public static string ShowSystemResources { + + /// <summary> + /// Looks up a localized string similar to Properties for the selected element. + /// </summary> + public static string PropertiesSelectedElement { get { - return ResourceManager.GetString("ShowSystemResources", resourceCulture); + return ResourceManager.GetString("PropertiesSelectedElement", resourceCulture); } } - - public static string ResourceEllipsis { + + /// <summary> + /// Looks up a localized string similar to Red. + /// </summary> + public static string Red { get { - return ResourceManager.GetString("ResourceEllipsis", resourceCulture); + return ResourceManager.GetString("Red", resourceCulture); } } - - public static string Default { + + /// <summary> + /// Looks up a localized string similar to Red / Green/ Blue. + /// </summary> + public static string RedGreenBlue { get { - return ResourceManager.GetString("Default", resourceCulture); + return ResourceManager.GetString("RedGreenBlue", resourceCulture); } } - - public static string Inherited { + + /// <summary> + /// Looks up a localized string similar to R. + /// </summary> + public static string RedInitial { get { - return ResourceManager.GetString("Inherited", resourceCulture); + return ResourceManager.GetString("RedInitial", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to Remove item. /// </summary> @@ -571,172 +878,238 @@ namespace Xamarin.PropertyEditing.Properties { return ResourceManager.GetString("RemoveItem", resourceCulture); } } - - public static string Local { + + /// <summary> + /// Looks up a localized string similar to Reset. + /// </summary> + public static string Reset { get { - return ResourceManager.GetString("Local", resourceCulture); + return ResourceManager.GetString("Reset", resourceCulture); } } - - public static string Unset { + + /// <summary> + /// Looks up a localized string similar to Resource. + /// </summary> + public static string Resource { get { - return ResourceManager.GetString("Unset", resourceCulture); + return ResourceManager.GetString("Resource", resourceCulture); } } - - public static string MaterialColorRed { + + /// <summary> + /// Looks up a localized string similar to Brush from resource. + /// </summary> + public static string ResourceBrush { get { - return ResourceManager.GetString("MaterialColorRed", resourceCulture); + return ResourceManager.GetString("ResourceBrush", resourceCulture); } } - - public static string MaterialColorPink { + + /// <summary> + /// Looks up a localized string similar to Resource dictionary. + /// </summary> + public static string ResourceDictionary { get { - return ResourceManager.GetString("MaterialColorPink", resourceCulture); + return ResourceManager.GetString("ResourceDictionary", resourceCulture); } } - - public static string MaterialColorPurple { + + /// <summary> + /// Looks up a localized string similar to Resource…. + /// </summary> + public static string ResourceEllipsis { get { - return ResourceManager.GetString("MaterialColorPurple", resourceCulture); + return ResourceManager.GetString("ResourceEllipsis", resourceCulture); } } - - public static string MaterialColorDeepPurple { + + /// <summary> + /// Looks up a localized string similar to Name. + /// </summary> + public static string ResourceNameLabel { get { - return ResourceManager.GetString("MaterialColorDeepPurple", resourceCulture); + return ResourceManager.GetString("ResourceNameLabel", resourceCulture); } } - - public static string MaterialColorIndigo { + + /// <summary> + /// Looks up a localized string similar to Resource ({0}). + /// </summary> + public static string ResourceWithName { get { - return ResourceManager.GetString("MaterialColorIndigo", resourceCulture); + return ResourceManager.GetString("ResourceWithName", resourceCulture); } } - - public static string MaterialColorBlue { + + /// <summary> + /// Looks up a localized string similar to RGB. + /// </summary> + public static string RGB { get { - return ResourceManager.GetString("MaterialColorBlue", resourceCulture); + return ResourceManager.GetString("RGB", resourceCulture); } } - - public static string MaterialColorLightBlue { + + /// <summary> + /// Looks up a localized string similar to Saturation. + /// </summary> + public static string Saturation { get { - return ResourceManager.GetString("MaterialColorLightBlue", resourceCulture); + return ResourceManager.GetString("Saturation", resourceCulture); } } - - public static string MaterialColorCyan { + + /// <summary> + /// Looks up a localized string similar to S. + /// </summary> + public static string SaturationInitial { get { - return ResourceManager.GetString("MaterialColorCyan", resourceCulture); + return ResourceManager.GetString("SaturationInitial", resourceCulture); } } - - public static string MaterialColorTeal { + + /// <summary> + /// Looks up a localized string similar to Search Objects. + /// </summary> + public static string SearchObjectsTitle { get { - return ResourceManager.GetString("MaterialColorTeal", resourceCulture); + return ResourceManager.GetString("SearchObjectsTitle", resourceCulture); } } - - public static string MaterialColorGreen { + + /// <summary> + /// Looks up a localized string similar to Search properties. + /// </summary> + public static string SearchProperties { get { - return ResourceManager.GetString("MaterialColorGreen", resourceCulture); + return ResourceManager.GetString("SearchProperties", resourceCulture); } } - - public static string MaterialColorLightGreen { + + /// <summary> + /// Looks up a localized string similar to Search Resources. + /// </summary> + public static string SearchResourcesTitle { get { - return ResourceManager.GetString("MaterialColorLightGreen", resourceCulture); + return ResourceManager.GetString("SearchResourcesTitle", resourceCulture); } } - - public static string MaterialColorLime { + + /// <summary> + /// Looks up a localized string similar to Select Object. + /// </summary> + public static string SelectObjectTitle { get { - return ResourceManager.GetString("MaterialColorLime", resourceCulture); + return ResourceManager.GetString("SelectObjectTitle", resourceCulture); } } - - public static string MaterialColorYellow { + + /// <summary> + /// Looks up a localized string similar to Select Resource. + /// </summary> + public static string SelectResourceTitle { get { - return ResourceManager.GetString("MaterialColorYellow", resourceCulture); + return ResourceManager.GetString("SelectResourceTitle", resourceCulture); } } - - public static string MaterialColorAmber { + + /// <summary> + /// Looks up a localized string similar to Show advanced properties. + /// </summary> + public static string ShowAdvancedProperties { get { - return ResourceManager.GetString("MaterialColorAmber", resourceCulture); + return ResourceManager.GetString("ShowAdvancedProperties", resourceCulture); } } - - public static string MaterialColorOrange { + + /// <summary> + /// Looks up a localized string similar to _Show all assemblies. + /// </summary> + public static string ShowAllAssemblies { get { - return ResourceManager.GetString("MaterialColorOrange", resourceCulture); + return ResourceManager.GetString("ShowAllAssemblies", resourceCulture); } } - - public static string MaterialColorDeepOrange { + + /// <summary> + /// Looks up a localized string similar to _Show system resources. + /// </summary> + public static string ShowSystemResources { get { - return ResourceManager.GetString("MaterialColorDeepOrange", resourceCulture); + return ResourceManager.GetString("ShowSystemResources", resourceCulture); } } - - public static string MaterialColorBrown { + + /// <summary> + /// Looks up a localized string similar to Solid color brush. + /// </summary> + public static string SolidBrush { get { - return ResourceManager.GetString("MaterialColorBrown", resourceCulture); + return ResourceManager.GetString("SolidBrush", resourceCulture); } } - - public static string MaterialColorGrey { + + /// <summary> + /// Looks up a localized string similar to This document. + /// </summary> + public static string ThisDocument { get { - return ResourceManager.GetString("MaterialColorGrey", resourceCulture); + return ResourceManager.GetString("ThisDocument", resourceCulture); } } - - public static string MaterialColorBlueGrey { + + /// <summary> + /// Looks up a localized string similar to Type. + /// </summary> + public static string Type { get { - return ResourceManager.GetString("MaterialColorBlueGrey", resourceCulture); + return ResourceManager.GetString("Type", resourceCulture); } } - - public static string MaterialDesignColorBrush { + + /// <summary> + /// Looks up a localized string similar to Unset. + /// </summary> + public static string Unset { get { - return ResourceManager.GetString("MaterialDesignColorBrush", resourceCulture); + return ResourceManager.GetString("Unset", resourceCulture); } } - - public static string MaterialColorBlackAndWhite { + + /// <summary> + /// Looks up a localized string similar to View properties or events. + /// </summary> + public static string ViewPropertiesOrEvents { get { - return ResourceManager.GetString("MaterialColorBlackAndWhite", resourceCulture); + return ResourceManager.GetString("ViewPropertiesOrEvents", resourceCulture); } } - + + /// <summary> + /// Looks up a localized string similar to White. + /// </summary> public static string White { get { return ResourceManager.GetString("White", resourceCulture); } } - - public static string NoPreviewAvailable { - get { - return ResourceManager.GetString("NoPreviewAvailable", resourceCulture); - } - } - - public static string Resource { - get { - return ResourceManager.GetString("Resource", resourceCulture); - } - } - - public static string ResourceWithName { + + /// <summary> + /// Looks up a localized string similar to Yellow. + /// </summary> + public static string Yellow { get { - return ResourceManager.GetString("ResourceWithName", resourceCulture); + return ResourceManager.GetString("Yellow", resourceCulture); } } - - public static string Binding { + + /// <summary> + /// Looks up a localized string similar to Y. + /// </summary> + public static string YellowInitial { get { - return ResourceManager.GetString("Binding", resourceCulture); + return ResourceManager.GetString("YellowInitial", resourceCulture); } } } diff --git a/Xamarin.PropertyEditing/Properties/Resources.resx b/Xamarin.PropertyEditing/Properties/Resources.resx index 15ed5c0..a6bd2c1 100644 --- a/Xamarin.PropertyEditing/Properties/Resources.resx +++ b/Xamarin.PropertyEditing/Properties/Resources.resx @@ -486,4 +486,32 @@ <data name="RemoveItem" xml:space="preserve"> <value>Remove item</value> </data> + <data name="GenericErrorMessage" xml:space="preserve"> + <value>Something went wrong</value> + </data> + <data name="DefineIn" xml:space="preserve"> + <value>Define in</value> + </data> + <data name="Application" xml:space="preserve"> + <value>Application</value> + </data> + <data name="ApplyToAll" xml:space="preserve"> + <value>Apply to all</value> + </data> + <data name="ThisDocument" xml:space="preserve"> + <value>This document</value> + </data> + <data name="ConvertToNewResourceEllipsis" xml:space="preserve"> + <value>Convert to new resource…</value> + </data> + <data name="CreateResourceTitle" xml:space="preserve"> + <value>Create {0} Resource</value> + <comment>Create {Type} Resource</comment> + </data> + <data name="ResourceNameLabel" xml:space="preserve"> + <value>Name</value> + </data> + <data name="ResourceDictionary" xml:space="preserve"> + <value>Resource dictionary</value> + </data> </root>
\ No newline at end of file diff --git a/Xamarin.PropertyEditing/ViewModels/CreateResourceRequestedEventArgs.cs b/Xamarin.PropertyEditing/ViewModels/CreateResourceRequestedEventArgs.cs new file mode 100644 index 0000000..0eca91b --- /dev/null +++ b/Xamarin.PropertyEditing/ViewModels/CreateResourceRequestedEventArgs.cs @@ -0,0 +1,19 @@ +using System; +namespace Xamarin.PropertyEditing.ViewModels +{ + internal class CreateResourceRequestedEventArgs + : EventArgs + { + public ResourceSource Source + { + get; + set; + } + + public string Name + { + get; + set; + } + } +} diff --git a/Xamarin.PropertyEditing/ViewModels/CreateResourceViewModel.cs b/Xamarin.PropertyEditing/ViewModels/CreateResourceViewModel.cs new file mode 100644 index 0000000..dfb20d4 --- /dev/null +++ b/Xamarin.PropertyEditing/ViewModels/CreateResourceViewModel.cs @@ -0,0 +1,395 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace Xamarin.PropertyEditing.ViewModels +{ + internal class CreateResourceViewModel + : NotifyingObject, INotifyDataErrorInfo + { + public CreateResourceViewModel (IResourceProvider provider, IEnumerable<object> targets, IPropertyInfo property) + { + if (provider == null) + throw new ArgumentNullException (nameof(provider)); + if (targets == null) + throw new ArgumentNullException (nameof(targets)); + if (property == null) + throw new ArgumentNullException (nameof(property)); + + this.provider = provider; + this.targets = targets.ToArray(); + this.property = property; + + CreateResourceCommand = new RelayCommand (OnCreateResource, CanCreateResource); + + LoadingTask = RequestSources (); + } + + public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; + public event EventHandler CreateResource; + + public IPropertyInfo Property => this.property; + + public string ResourceKey + { + get { return this.resourceKey; } + set + { + if (this.resourceKey == value) + return; + + this.resourceKey = value; + OnPropertyChanged(); + ((RelayCommand)CreateResourceCommand).ChangeCanExecute(); + + if (SelectedResourceSource != null) + RequestErrorCheck(); + } + } + + public bool IsKeyed + { + get { return this.isKeyed; } + set + { + if (this.isKeyed == value) + return; + + this.isKeyed = value; + OnPropertyChanged (); + OnPropertyChanged (nameof(IsAppliedToAll)); + } + } + + public bool IsAppliedToAll + { + get { return !this.isKeyed; } // Reverse on isKeyed for easier binding + set + { + if (this.isKeyed == !value) + return; + + this.isKeyed = !value; + OnPropertyChanged (); + OnPropertyChanged (nameof (IsKeyed)); + } + } + + public bool CanApplyToAll + { + get; + } = false; // Support for this to come later (requires a different in-point) + + public ResourceSource SelectedResourceSource + { + get { return this.selectedSource; } + set + { + if (this.selectedSource == value) + return; + + this.selectedSource = value; + OnPropertyChanged(); + RequestErrorCheck (); + ((RelayCommand)CreateResourceCommand).ChangeCanExecute(); + } + } + + public bool DefineInApplication + { + get { return this.defineIn == ResourceSourceType.Application; } + set + { + if (DefineInApplication == value) + return; + + if (!value) { + DefineInDocument = true; + return; + } + + this.defineIn = ResourceSourceType.Application; + OnPropertyChanged (); + OnPropertyChanged (nameof(DefineInDocument)); + OnPropertyChanged (nameof(DefineInApplicationSource)); + SelectedResourceSource = this.applicationSource; + } + } + + public bool DefineInDocument + { + get { return this.defineIn == ResourceSourceType.Document; } + set + { + if (DefineInDocument == value) + return; + + if (value) { + this.defineIn = ResourceSourceType.Document; + SelectedResourceSource = SelectedDocumentSource; + } else { + DefineInApplication = true; + return; + } + + OnPropertyChanged (); + OnPropertyChanged (nameof(DefineInApplication)); + OnPropertyChanged (nameof(DefineInApplicationSource)); + } + } + + public ResourceSource SelectedDocumentSource + { + get { return this.selectedDocSource; } + set + { + if (this.selectedDocSource == value) + return; + + this.selectedDocSource = value; + OnPropertyChanged(); + SelectedResourceSource = value; + } + } + + public bool DefineInApplicationSource + { + get { return this.defineIn == ResourceSourceType.ResourceDictionary; } + set { + if (DefineInApplicationSource == value) + return; + + if (value) { + this.defineIn = ResourceSourceType.ResourceDictionary; + SelectedResourceSource = SelectedApplicationSource; + } else { + DefineInApplication = true; + return; + } + + OnPropertyChanged (); + OnPropertyChanged (nameof (DefineInApplication)); + OnPropertyChanged (nameof (DefineInDocument)); + } + } + + public ResourceSource SelectedApplicationSource + { + get { return this.selectedDictSource; } + set + { + if (this.selectedDictSource == value) + return; + + this.selectedDictSource = value; + OnPropertyChanged(); + SelectedResourceSource = value; + } + } + + public bool HasApplicationSources => (ApplicationSources?.Count ?? 0) > 0; + + public IReadOnlyList<ResourceSource> ApplicationSources + { + get { return this.applicationSources; } + private set + { + if (this.applicationSources == value) + return; + + this.applicationSources = value; + OnPropertyChanged (); + OnPropertyChanged (nameof(HasApplicationSources)); + } + } + + public bool HasDocumentSources => (DocumentSources?.Count ?? 0) > 0; + + public IReadOnlyList<ResourceSource> DocumentSources + { + get { return this.documentSources; } + private set + { + if (this.documentSources == value) + return; + + this.documentSources = value; + OnPropertyChanged (); + OnPropertyChanged (nameof(HasDocumentSources)); + } + } + + public ICommand CreateResourceCommand + { + get; + } + + public Task LoadingTask + { + get; + } + + public bool IsLoading + { + get { return this.isLoading; } + private set + { + if (this.isLoading == value) + return; + + this.isLoading = value; + OnPropertyChanged(); + } + } + + public bool HasErrors + { + get { return this.errors.Count > 0; } + } + + public bool HasFatalError + { + get { return FatalError != null; } + } + + public string FatalError + { + get { return this.fatalError; } + private set + { + if (this.fatalError == value) + return; + + this.fatalError = value; + OnPropertyChanged (); + OnPropertyChanged (nameof(HasFatalError)); + ((RelayCommand)CreateResourceCommand).ChangeCanExecute(); + } + } + + public IEnumerable GetErrors (string propertyName) + { + if (this.errors.TryGetValue (propertyName, out Tuple<string, bool> error) && error != null) + return new string[] { error.Item1 }; + else + return Enumerable.Empty<string> (); + } + + private readonly IPropertyInfo property; + + private ResourceSource selectedSource, selectedDictSource, selectedDocSource; + private ResourceSource applicationSource; + private IReadOnlyList<ResourceSource> applicationSources; + private IReadOnlyList<ResourceSource> documentSources; + private ResourceSourceType defineIn; + private bool isKeyed = true; + private string resourceKey; + private bool isLoading = true; + private string fatalError; + + private readonly Dictionary<string, Tuple<string, bool>> errors = new Dictionary<string, Tuple<string, bool>> (); + private readonly IResourceProvider provider; + private readonly object[] targets; + + private void SetError (string propertyName, Tuple<string, bool> incoming) + { + bool signal = false; + if (incoming == null) + signal = this.errors.Remove (propertyName); + else { + if (signal = !this.errors.TryGetValue (propertyName, out Tuple<string, bool> current) || !Equals (current, incoming)) + this.errors[propertyName] = incoming; + } + + if (signal) { + OnPropertyChanged (nameof(HasErrors)); + ErrorsChanged?.Invoke (this, new DataErrorsChangedEventArgs (propertyName)); + ((RelayCommand)CreateResourceCommand).ChangeCanExecute(); + } + } + + private async Task RequestSources () + { + var appSources = new List<ResourceSource> (); + var docSources = new List<ResourceSource> (); + + Task suggestedNameTask = RequestSuggestedName (); + + // Not sorted on purpose; we want implementers to be able to importance by order (ex. document hierarchy). + try { + var allSources = await Task.WhenAll (this.targets.Select (t => this.provider.GetResourceSourcesAsync (t, this.property))); + IEnumerable<ResourceSource> sources = allSources[0]; + if (allSources.Length > 1) { + HashSet<ResourceSource> commonSources = new HashSet<ResourceSource> (allSources[0]); + for (int i = 1; i < allSources.Length; i++) { + commonSources.IntersectWith (allSources[i]); + } + + sources = allSources[0].Where (s => commonSources.Contains (s)); + } + + foreach (ResourceSource source in sources) { + if (source.Type == ResourceSourceType.Application) { + this.applicationSource = source; + } else if (source.Type == ResourceSourceType.ResourceDictionary) + appSources.Add (source); + else if (source.Type == ResourceSourceType.Document) + docSources.Add (source); + } + + if (this.applicationSource == null) + throw new NotSupportedException ("You must define an application level resource source."); + + ApplicationSources = appSources; + SelectedApplicationSource = appSources.FirstOrDefault (); + DocumentSources = docSources; + SelectedDocumentSource = docSources.FirstOrDefault (); + DefineInApplication = true; + await suggestedNameTask; + } catch (Exception ex) { + FatalError = ex.Message; + } finally { + IsLoading = false; + } + } + + private async void RequestErrorCheck () + { + if (!String.IsNullOrEmpty (ResourceKey)) { + try { + foreach (object target in this.targets) { + ResourceCreateError error = await this.provider.CheckNameErrorsAsync (target, SelectedResourceSource, ResourceKey); + SetError (nameof(ResourceKey), error != null ? new Tuple<string, bool> (error.Message, error.IsWarning) : null); + if (error != null) + break; + } + } catch (Exception ex) { + FatalError = ex.Message; + } + } else { + SetError (nameof(ResourceKey), null); + } + } + + private async Task RequestSuggestedName () + { + string suggested = await this.provider.SuggestResourceNameAsync (this.targets, this.property); + if (String.IsNullOrWhiteSpace (ResourceKey)) + ResourceKey = suggested; + } + + private bool CanCreateResource () + { + return !String.IsNullOrWhiteSpace (ResourceKey) && SelectedResourceSource != null && !(this.errors.Any (kvp => !kvp.Value.Item2)) && !HasFatalError; + } + + private void OnCreateResource () + { + CreateResource?.Invoke (this, EventArgs.Empty); + } + } +}
\ No newline at end of file diff --git a/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs b/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs index b64ff07..b9bd37e 100644 --- a/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs +++ b/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs @@ -28,10 +28,11 @@ namespace Xamarin.PropertyEditing.ViewModels this.valueNavigator = property as ICanNavigateToSource; this.isNullable = (!property.ValueSources.HasFlag (ValueSources.Default) || property.Type.Name == NullableName); + RequestCreateResourceCommand = new RelayCommand (OnCreateResource, CanCreateResource); NavigateToValueSourceCommand = new RelayCommand (OnNavigateToSource, CanNavigateToSource); SetValueResourceCommand = new RelayCommand<Resource> (OnSetValueToResource, CanSetValueToResource); ClearValueCommand = new RelayCommand (OnClearValue, CanClearValue); - ConvertToLocalValueCommand = new RelayCommand(OnConvertToLocalValue, CanClearToLocalValue); + ConvertToLocalValueCommand = new RelayCommand (OnConvertToLocalValue, CanClearToLocalValue); RequestCurrentValueUpdate(); } @@ -106,10 +107,11 @@ namespace Xamarin.PropertyEditing.ViewModels } /// <remarks> - /// For updating property-type-specific value properties, override this. <see cref="PropertyViewModel.MultipleValues"/> <see cref="Value"/> is up to date + /// For updating property-type-specific value properties, override this. <see cref="PropertyViewModel.MultipleValues"/> <see cref="Value"/> is up to date. /// </remarks> protected virtual void OnValueChanged () { + ((RelayCommand)RequestCreateResourceCommand)?.ChangeCanExecute(); } /// <summary> @@ -299,6 +301,21 @@ namespace Xamarin.PropertyEditing.ViewModels this.valueNavigator?.NavigateToSource (Editors.FirstOrDefault ()); } + private bool CanCreateResource () + { + return SupportsResources && ResourceProvider != null && !MultipleValues; + } + + private async void OnCreateResource () + { + var e = RequestCreateResource (); + if (e.Source == null) + return; + + Resource resource = await ResourceProvider.CreateResourceAsync (e.Source, e.Name, Value); + OnSetValueToResource (resource); + } + private static TValue DefaultValue; } @@ -318,6 +335,7 @@ namespace Xamarin.PropertyEditing.ViewModels } public event EventHandler<ResourceRequestedEventArgs> ResourceRequested; + public event EventHandler<CreateResourceRequestedEventArgs> CreateResourceRequested; public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; public IPropertyInfo Property @@ -348,6 +366,11 @@ namespace Xamarin.PropertyEditing.ViewModels get { return Property.CanWrite && Property.ValueSources.HasFlag (ValueSources.Resource); } } + public bool CanCreateResources + { + get { return SupportsResources && (ResourceProvider?.CanCreateResources ?? false); } + } + public abstract Resource Resource { get; @@ -391,6 +414,12 @@ namespace Xamarin.PropertyEditing.ViewModels public ICommand RequestResourceCommand => this.requestResourceCommand; + public ICommand RequestCreateResourceCommand + { + get; + protected set; + } + public ICommand ClearValueCommand { get; @@ -486,9 +515,16 @@ namespace Xamarin.PropertyEditing.ViewModels editor.PropertyChanged -= OnEditorPropertyChanged; } + protected CreateResourceRequestedEventArgs RequestCreateResource () + { + var e = new CreateResourceRequestedEventArgs (); + CreateResourceRequested?.Invoke (this, e); + return e; + } + + private readonly RelayCommand requestResourceCommand; private IResourceProvider resourceProvider; private ICommand setValueResourceCommand; - private RelayCommand requestResourceCommand; private HashSet<IPropertyInfo> constraintProperties; private PropertyVariation variation; private string error; @@ -569,7 +605,7 @@ namespace Xamarin.PropertyEditing.ViewModels private void OnSetValueResourceCommandCanExecuteChanged (object sender, EventArgs e) { - this.requestResourceCommand.ChangeCanExecute(); + ((RelayCommand)RequestResourceCommand)?.ChangeCanExecute(); } } } diff --git a/Xamarin.PropertyEditing/Xamarin.PropertyEditing.csproj b/Xamarin.PropertyEditing/Xamarin.PropertyEditing.csproj index 5de9788..64622a4 100644 --- a/Xamarin.PropertyEditing/Xamarin.PropertyEditing.csproj +++ b/Xamarin.PropertyEditing/Xamarin.PropertyEditing.csproj @@ -114,6 +114,8 @@ <Compile Include="ViewModels\ArrangeModeViewModel.cs" /> <Compile Include="ViewModels\BrushPropertyViewModel.cs" /> <Compile Include="ViewModels\CollectionPropertyViewModel.cs" /> + <Compile Include="ViewModels\CreateResourceRequestedEventArgs.cs" /> + <Compile Include="ViewModels\CreateResourceViewModel.cs" /> <Compile Include="ViewModels\MaterialColorScale.cs" /> <Compile Include="ViewModels\MaterialDesignColorViewModel.cs" /> <Compile Include="ViewModels\CombinablePropertyViewModel.cs" /> |