From 20c1bd6c22392a585297bc7a6b6a9010887346cf Mon Sep 17 00:00:00 2001 From: jkuehner Date: Sat, 27 Dec 2014 14:47:27 +0100 Subject: [PATCH] Items Control should have a Transp. Background so it can be used as a Drop Target --- .../Extensions/PanelInstanceFactory.cs | 141 ++++------------- ...lueInsteadOfNullTypeDescriptionProvider.cs | 142 ++++++++++++++++++ .../WpfDesign/Project/WpfDesign.csproj | 1 + 3 files changed, 169 insertions(+), 115 deletions(-) create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DummyValueInsteadOfNullTypeDescriptionProvider.cs diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelInstanceFactory.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelInstanceFactory.cs index 3da7397e10..6b12abe3d7 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelInstanceFactory.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelInstanceFactory.cs @@ -79,6 +79,32 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } } + [ExtensionFor(typeof(ItemsControl))] + public sealed class TransparentControlsInstanceFactory : CustomInstanceFactory + { + Brush _transparentBrush = new SolidColorBrush(Colors.Transparent); + + /// + /// Creates an instance of the specified type, passing the specified arguments to its constructor. + /// + public override object CreateInstance(Type type, params object[] arguments) + { + object instance = base.CreateInstance(type, arguments); + Control control = instance as Control; + if (control != null && ( + type == typeof(ItemsControl))) { + if (control.Background == null) { + control.Background = _transparentBrush; + } + + TypeDescriptionProvider provider = new DummyValueInsteadOfNullTypeDescriptionProvider( + TypeDescriptor.GetProvider(control), "Background", _transparentBrush); + TypeDescriptor.AddProvider(provider, control); + } + return instance; + } + } + [ExtensionFor(typeof(Border))] public sealed class BorderInstanceFactory : CustomInstanceFactory { @@ -104,119 +130,4 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions return instance; } } - - sealed class DummyValueInsteadOfNullTypeDescriptionProvider : TypeDescriptionProvider - { - // By using a TypeDescriptionProvider, we can intercept all access to the property that is - // using a PropertyDescriptor. WpfDesign.XamlDom uses a PropertyDescriptor for accessing - // properties (except for attached properties), so even DesignItemProperty/XamlProperty.ValueOnInstance - // will report null when the actual value is the dummy value. - - readonly string _propertyName; - readonly object _dummyValue; - - public DummyValueInsteadOfNullTypeDescriptionProvider(TypeDescriptionProvider existingProvider, - string propertyName, object dummyValue) - : base(existingProvider) - { - this._propertyName = propertyName; - this._dummyValue = dummyValue; - } - - public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) - { - return new ShadowTypeDescriptor(this, base.GetTypeDescriptor(objectType, instance)); - } - - sealed class ShadowTypeDescriptor : CustomTypeDescriptor - { - readonly DummyValueInsteadOfNullTypeDescriptionProvider _parent; - - public ShadowTypeDescriptor(DummyValueInsteadOfNullTypeDescriptionProvider parent, - ICustomTypeDescriptor existingDescriptor) - : base(existingDescriptor) - { - this._parent = parent; - } - - public override PropertyDescriptorCollection GetProperties() - { - return Filter(base.GetProperties()); - } - - public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) - { - return Filter(base.GetProperties(attributes)); - } - - PropertyDescriptorCollection Filter(PropertyDescriptorCollection properties) - { - PropertyDescriptor property = properties[_parent._propertyName]; - if (property != null) { - if ((properties as System.Collections.IDictionary).IsReadOnly) { - properties = new PropertyDescriptorCollection(properties.Cast().ToArray()); - } - properties.Remove(property); - properties.Add(new ShadowPropertyDescriptor(_parent, property)); - } - return properties; - } - } - - sealed class ShadowPropertyDescriptor : PropertyDescriptor - { - readonly DummyValueInsteadOfNullTypeDescriptionProvider _parent; - readonly PropertyDescriptor _baseDescriptor; - - public ShadowPropertyDescriptor(DummyValueInsteadOfNullTypeDescriptionProvider parent, - PropertyDescriptor existingDescriptor) - : base(existingDescriptor) - { - this._parent = parent; - this._baseDescriptor = existingDescriptor; - } - - public override Type ComponentType { - get { return _baseDescriptor.ComponentType; } - } - - public override bool IsReadOnly { - get { return _baseDescriptor.IsReadOnly; } - } - - public override Type PropertyType { - get { return _baseDescriptor.PropertyType; } - } - - public override bool CanResetValue(object component) - { - return _baseDescriptor.CanResetValue(component); - } - - public override object GetValue(object component) - { - object value = _baseDescriptor.GetValue(component); - if (value == _parent._dummyValue) - return null; - else - return value; - } - - public override void ResetValue(object component) - { - _baseDescriptor.SetValue(component, _parent._dummyValue); - } - - public override void SetValue(object component, object value) - { - _baseDescriptor.SetValue(component, value ?? _parent._dummyValue); - } - - public override bool ShouldSerializeValue(object component) - { - return _baseDescriptor.ShouldSerializeValue(component) - && _baseDescriptor.GetValue(component) != _parent._dummyValue; - } - } - } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DummyValueInsteadOfNullTypeDescriptionProvider.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DummyValueInsteadOfNullTypeDescriptionProvider.cs new file mode 100644 index 0000000000..2834cabe6b --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DummyValueInsteadOfNullTypeDescriptionProvider.cs @@ -0,0 +1,142 @@ +// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.ComponentModel; +using System.Linq; + +namespace ICSharpCode.WpfDesign +{ + /// + /// Description of DummyValueInsteadOfNullTypeDescriptionProvider. + /// + public sealed class DummyValueInsteadOfNullTypeDescriptionProvider : TypeDescriptionProvider + { + // By using a TypeDescriptionProvider, we can intercept all access to the property that is + // using a PropertyDescriptor. WpfDesign.XamlDom uses a PropertyDescriptor for accessing + // properties (except for attached properties), so even DesignItemProperty/XamlProperty.ValueOnInstance + // will report null when the actual value is the dummy value. + + readonly string _propertyName; + readonly object _dummyValue; + + public DummyValueInsteadOfNullTypeDescriptionProvider(TypeDescriptionProvider existingProvider, + string propertyName, object dummyValue) + : base(existingProvider) + { + this._propertyName = propertyName; + this._dummyValue = dummyValue; + } + + public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) + { + return new ShadowTypeDescriptor(this, base.GetTypeDescriptor(objectType, instance)); + } + + sealed class ShadowTypeDescriptor : CustomTypeDescriptor + { + readonly DummyValueInsteadOfNullTypeDescriptionProvider _parent; + + public ShadowTypeDescriptor(DummyValueInsteadOfNullTypeDescriptionProvider parent, + ICustomTypeDescriptor existingDescriptor) + : base(existingDescriptor) + { + this._parent = parent; + } + + public override PropertyDescriptorCollection GetProperties() + { + return Filter(base.GetProperties()); + } + + public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) + { + return Filter(base.GetProperties(attributes)); + } + + PropertyDescriptorCollection Filter(PropertyDescriptorCollection properties) + { + PropertyDescriptor property = properties[_parent._propertyName]; + if (property != null) { + if ((properties as System.Collections.IDictionary).IsReadOnly) { + properties = new PropertyDescriptorCollection(properties.Cast().ToArray()); + } + properties.Remove(property); + properties.Add(new ShadowPropertyDescriptor(_parent, property)); + } + return properties; + } + } + + sealed class ShadowPropertyDescriptor : PropertyDescriptor + { + readonly DummyValueInsteadOfNullTypeDescriptionProvider _parent; + readonly PropertyDescriptor _baseDescriptor; + + public ShadowPropertyDescriptor(DummyValueInsteadOfNullTypeDescriptionProvider parent, + PropertyDescriptor existingDescriptor) + : base(existingDescriptor) + { + this._parent = parent; + this._baseDescriptor = existingDescriptor; + } + + public override Type ComponentType { + get { return _baseDescriptor.ComponentType; } + } + + public override bool IsReadOnly { + get { return _baseDescriptor.IsReadOnly; } + } + + public override Type PropertyType { + get { return _baseDescriptor.PropertyType; } + } + + public override bool CanResetValue(object component) + { + return _baseDescriptor.CanResetValue(component); + } + + public override object GetValue(object component) + { + object value = _baseDescriptor.GetValue(component); + if (value == _parent._dummyValue) + return null; + else + return value; + } + + public override void ResetValue(object component) + { + _baseDescriptor.SetValue(component, _parent._dummyValue); + } + + public override void SetValue(object component, object value) + { + _baseDescriptor.SetValue(component, value ?? _parent._dummyValue); + } + + public override bool ShouldSerializeValue(object component) + { + return _baseDescriptor.ShouldSerializeValue(component) + && _baseDescriptor.GetValue(component) != _parent._dummyValue; + } + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj index 7bc841aa26..ebc325f1c0 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj @@ -73,6 +73,7 @@ +