Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2258 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
27 changed files with 701 additions and 329 deletions
@ -0,0 +1,159 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.ComponentModel; |
||||||
|
using System.Windows.Media; |
||||||
|
using System.Windows.Controls; |
||||||
|
using ICSharpCode.WpfDesign.Extensions; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign.Designer.Extensions |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Instance factory used to create Panel instances.
|
||||||
|
/// Sets the panels Brush to a transparent brush, and modifies the panel's type descriptor so that
|
||||||
|
/// setting the Brush to null actually restores the transparent brush.
|
||||||
|
/// </summary>
|
||||||
|
[ExtensionFor(typeof(Panel))] |
||||||
|
public class PanelInstanceFactory : CustomInstanceFactory |
||||||
|
{ |
||||||
|
Brush _transparentBrush = new SolidColorBrush(Colors.Transparent); |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates an instance of the specified type, passing the specified arguments to its constructor.
|
||||||
|
/// </summary>
|
||||||
|
public override object CreateInstance(Type type, params object[] arguments) |
||||||
|
{ |
||||||
|
object instance = base.CreateInstance(type, arguments); |
||||||
|
Panel panel = instance as Panel; |
||||||
|
if (panel != null) { |
||||||
|
if (panel.Background == null) { |
||||||
|
panel.Background = _transparentBrush; |
||||||
|
} |
||||||
|
TypeDescriptionProvider provider = new DummyValueInsteadOfNullTypeDescriptionProvider( |
||||||
|
TypeDescriptor.GetProvider(panel), "Background", _transparentBrush); |
||||||
|
TypeDescriptor.AddProvider(provider, panel); |
||||||
|
} |
||||||
|
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(Linq.ToArray(properties)); |
||||||
|
} |
||||||
|
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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign.Designer.Services |
||||||
|
{ |
||||||
|
sealed class DefaultViewService : ViewService |
||||||
|
{ |
||||||
|
readonly DesignContext context; |
||||||
|
|
||||||
|
public DefaultViewService(DesignContext context) |
||||||
|
{ |
||||||
|
this.context = context; |
||||||
|
} |
||||||
|
|
||||||
|
public override DesignItem GetModel(System.Windows.DependencyObject view) |
||||||
|
{ |
||||||
|
// In the WPF designer, we do not support having a different view for a component
|
||||||
|
return context.Services.Component.GetDesignItem(view); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,69 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Media; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Services |
|
||||||
{ |
|
||||||
sealed class DefaultVisualDesignService : IVisualDesignService |
|
||||||
{ |
|
||||||
public UIElement CreateWrapper(DesignItem site) |
|
||||||
{ |
|
||||||
if (site == null) |
|
||||||
throw new ArgumentNullException("site"); |
|
||||||
|
|
||||||
object obj = site.Component; |
|
||||||
|
|
||||||
if (obj is UIElement) |
|
||||||
return null; |
|
||||||
else |
|
||||||
return new FallbackObjectWrapper(site); |
|
||||||
} |
|
||||||
|
|
||||||
internal static UIElement CreateUIElementFor(DesignItem site) |
|
||||||
{ |
|
||||||
IVisualDesignService service = site.Services.GetService<IVisualDesignService>(); |
|
||||||
if (service == null) |
|
||||||
throw new ServiceRequiredException(typeof(IVisualDesignService)); |
|
||||||
UIElement element = service.CreateWrapper(site); |
|
||||||
if (element != null) { |
|
||||||
if (!(element is IVisualDesignObjectWrapper)) { |
|
||||||
throw new DesignerException("IVisualDesignService.CreateWrapper must return null or UIElement implementing IVisualDesignObjectWrapper"); |
|
||||||
} |
|
||||||
} else { |
|
||||||
element = site.Component as UIElement; |
|
||||||
if (element == null) { |
|
||||||
throw new DesignerException("IVisualDesignService.CreateWrapper may not return null if site.Component is no UIElement"); |
|
||||||
} |
|
||||||
} |
|
||||||
return element; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class FallbackObjectWrapper : ContentControl, IVisualDesignObjectWrapper |
|
||||||
{ |
|
||||||
DesignItem _site; |
|
||||||
|
|
||||||
public FallbackObjectWrapper(DesignItem site) |
|
||||||
{ |
|
||||||
this._site = site; |
|
||||||
|
|
||||||
this.BorderThickness = new Thickness(1); |
|
||||||
this.BorderBrush = Brushes.Black; |
|
||||||
this.Background = Brushes.White; |
|
||||||
this.Foreground = Brushes.Black; |
|
||||||
this.Content = site.Component; |
|
||||||
} |
|
||||||
|
|
||||||
public DesignItem WrappedSite { |
|
||||||
get { return _site; } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,109 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Windows.Media; |
||||||
|
using ICSharpCode.WpfDesign.Adorners; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Describes the result of a <see cref="IDesignPanel.HitTest"/> call.
|
||||||
|
/// </summary>
|
||||||
|
public struct DesignPanelHitTestResult : IEquatable<DesignPanelHitTestResult> |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Represents the result that nothing was hit.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DesignPanelHitTestResult NoHit = new DesignPanelHitTestResult(); |
||||||
|
|
||||||
|
readonly Visual _visualHit; |
||||||
|
AdornerPanel _adornerHit; |
||||||
|
DesignItem _modelHit; |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The actual visual that was hit.
|
||||||
|
/// </summary>
|
||||||
|
public Visual VisualHit { |
||||||
|
get { return _visualHit; } |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The adorner panel containing the adorner that was hit.
|
||||||
|
/// </summary>
|
||||||
|
public AdornerPanel AdornerHit { |
||||||
|
get { return _adornerHit; } |
||||||
|
set { _adornerHit = value; } |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The model item that was hit.
|
||||||
|
/// </summary>
|
||||||
|
public DesignItem ModelHit { |
||||||
|
get { return _modelHit; } |
||||||
|
set { _modelHit = value; } |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new DesignPanelHitTestResult instance.
|
||||||
|
/// </summary>
|
||||||
|
public DesignPanelHitTestResult(Visual visualHit) |
||||||
|
{ |
||||||
|
this._visualHit = visualHit; |
||||||
|
this._adornerHit = null; |
||||||
|
this._modelHit = null; |
||||||
|
} |
||||||
|
|
||||||
|
#region Equals and GetHashCode implementation
|
||||||
|
// The code in this region is useful if you want to use this structure in collections.
|
||||||
|
// If you don't need it, you can just remove the region and the ": IEquatable<DesignPanelHitTestResult>" declaration.
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests if this hit test result equals the other result.
|
||||||
|
/// </summary>
|
||||||
|
public override bool Equals(object obj) |
||||||
|
{ |
||||||
|
if (obj is DesignPanelHitTestResult) |
||||||
|
return Equals((DesignPanelHitTestResult)obj); // use Equals method below
|
||||||
|
else |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests if this hit test result equals the other result.
|
||||||
|
/// </summary>
|
||||||
|
public bool Equals(DesignPanelHitTestResult other) |
||||||
|
{ |
||||||
|
// add comparisions for all members here
|
||||||
|
return _visualHit == other._visualHit && _adornerHit == other._adornerHit && _modelHit == other._modelHit; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the hash code.
|
||||||
|
/// </summary>
|
||||||
|
public override int GetHashCode() |
||||||
|
{ |
||||||
|
// combine the hash codes of all members here (e.g. with XOR operator ^)
|
||||||
|
return (_visualHit != null ? _visualHit.GetHashCode() : 0) |
||||||
|
^ (_adornerHit != null ? _adornerHit.GetHashCode() : 0) |
||||||
|
^ (_modelHit != null ? _modelHit.GetHashCode() : 0); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary/>
|
||||||
|
public static bool operator ==(DesignPanelHitTestResult lhs, DesignPanelHitTestResult rhs) |
||||||
|
{ |
||||||
|
return lhs.Equals(rhs); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary/>
|
||||||
|
public static bool operator !=(DesignPanelHitTestResult lhs, DesignPanelHitTestResult rhs) |
||||||
|
{ |
||||||
|
return !(lhs.Equals(rhs)); // use operator == and negate result
|
||||||
|
} |
||||||
|
#endregion
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign.Extensions |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Base class for extensions that initialize new controls with default values.
|
||||||
|
/// </summary>
|
||||||
|
[ExtensionServer(typeof(NeverApplyExtensionsExtensionServer))] |
||||||
|
public abstract class DefaultInitializer : Extension |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Initializes the design item to default values.
|
||||||
|
/// </summary>
|
||||||
|
public abstract void InitializeDefaults(DesignItem item); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue