Browse Source

Support CustomInstanceFactory.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2225 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
e2b69e1104
  1. 7
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs
  2. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs
  3. 14
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TabItemClickableExtension.cs
  4. 25
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignContext.cs
  5. 1
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/WpfDesign.XamlDom.csproj
  6. 55
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
  7. 49
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParserSettings.cs
  8. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Tests/TestHelper.cs
  9. 30
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs
  10. 1
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/BehaviorExtension.cs
  11. 63
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/CustomInstanceFactory.cs
  12. 10
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/ExtensionManager.cs
  13. 11
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Tools.cs
  14. 1
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj

7
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs

@ -77,12 +77,19 @@ namespace ICSharpCode.WpfDesign.Designer
if (!_isInInputAction) { if (!_isInInputAction) {
Debug.WriteLine("DesignPanel.PreviewMouseDown Source=" + e.Source.GetType().Name + " OriginalSource=" + e.OriginalSource.GetType().Name); Debug.WriteLine("DesignPanel.PreviewMouseDown Source=" + e.Source.GetType().Name + " OriginalSource=" + e.OriginalSource.GetType().Name);
DesignItem site = FindDesignedElementForOriginalSource(e.OriginalSource); DesignItem site = FindDesignedElementForOriginalSource(e.OriginalSource);
InputHandlingLayer itemLayer = InputHandlingLayer.None;
if (site != null) { if (site != null) {
Debug.WriteLine(" Found designed element: " + site.Component.GetType().Name); Debug.WriteLine(" Found designed element: " + site.Component.GetType().Name);
IProvideComponentInputHandlingLayer layerProvider = site.GetBehavior<IProvideComponentInputHandlingLayer>();
if (layerProvider != null) {
itemLayer = layerProvider.InputLayer;
} }
}
if (ToolService.CurrentTool.InputLayer > itemLayer) {
ToolService.CurrentTool.OnMouseDown(this, e); ToolService.CurrentTool.OnMouseDown(this, e);
} }
} }
}
public DesignItem FindDesignedElementForOriginalSource(object originalSource) public DesignItem FindDesignedElementForOriginalSource(object originalSource)
{ {

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs

@ -58,7 +58,7 @@ namespace ICSharpCode.WpfDesign.Designer
public void LoadDesigner(XmlReader xamlReader) public void LoadDesigner(XmlReader xamlReader)
{ {
UnloadDesigner(); UnloadDesigner();
InitializeDesigner(new Xaml.XamlDesignContext(XamlDom.XamlParser.Parse(xamlReader))); InitializeDesigner(new Xaml.XamlDesignContext(xamlReader));
} }
/// <summary> /// <summary>

14
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TabItemClickableExtension.cs

@ -13,11 +13,21 @@ using ICSharpCode.WpfDesign.Extensions;
namespace ICSharpCode.WpfDesign.Designer.Extensions namespace ICSharpCode.WpfDesign.Designer.Extensions
{ {
/// <summary> /// <summary>
/// Makes the TabItem clickable. /// Makes TabItems clickable.
/// </summary> /// </summary>
[ExtensionFor(typeof(TabItem))] [ExtensionFor(typeof(TabItem))]
public sealed class TabItemClickableExtension : BehaviorExtension public sealed class TabItemClickableExtension : BehaviorExtension, IProvideComponentInputHandlingLayer
{ {
/// <summary/>
protected override void OnInitialized()
{
this.ExtendedItem.AddBehavior(typeof(IProvideComponentInputHandlingLayer), this);
}
InputHandlingLayer IProvideComponentInputHandlingLayer.InputLayer {
get {
return InputHandlingLayer.ComponentHigh;
}
}
} }
} }

25
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignContext.cs

@ -6,8 +6,10 @@
// </file> // </file>
using System; using System;
using System.Xml;
using ICSharpCode.WpfDesign.XamlDom; using ICSharpCode.WpfDesign.XamlDom;
using ICSharpCode.WpfDesign.Designer.Services; using ICSharpCode.WpfDesign.Designer.Services;
using ICSharpCode.WpfDesign.Extensions;
namespace ICSharpCode.WpfDesign.Designer.Xaml namespace ICSharpCode.WpfDesign.Designer.Xaml
{ {
@ -17,11 +19,10 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
readonly XamlDesignItem _rootItem; readonly XamlDesignItem _rootItem;
readonly XamlComponentService _componentService; readonly XamlComponentService _componentService;
public XamlDesignContext(XamlDocument doc) public XamlDesignContext(XmlReader xamlReader)
{ {
if (doc == null) if (xamlReader == null)
throw new ArgumentNullException("doc"); throw new ArgumentNullException("xamlReader");
this._doc = doc;
this.Services.AddService(typeof(IVisualDesignService), new DefaultVisualDesignService()); this.Services.AddService(typeof(IVisualDesignService), new DefaultVisualDesignService());
this.Services.AddService(typeof(ISelectionService), new DefaultSelectionService()); this.Services.AddService(typeof(ISelectionService), new DefaultSelectionService());
@ -33,7 +34,21 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
// register extensions from this assembly: // register extensions from this assembly:
this.Services.ExtensionManager.RegisterAssembly(typeof(XamlDesignContext).Assembly); this.Services.ExtensionManager.RegisterAssembly(typeof(XamlDesignContext).Assembly);
_rootItem = _componentService.RegisterXamlComponentRecursive(doc.RootElement); XamlParserSettings xamlParseSettings = new XamlParserSettings();
xamlParseSettings.CreateInstanceCallback = OnXamlParserCreateInstance;
_doc = XamlParser.Parse(xamlReader, xamlParseSettings);
_rootItem = _componentService.RegisterXamlComponentRecursive(_doc.RootElement);
}
object OnXamlParserCreateInstance(Type instanceType, object[] arguments)
{
foreach (Type extensionType in this.Services.ExtensionManager.GetExtensionTypes(instanceType)) {
if (typeof(CustomInstanceFactory).IsAssignableFrom(extensionType)) {
CustomInstanceFactory factory = (CustomInstanceFactory)Activator.CreateInstance(extensionType);
return factory.CreateInstance(instanceType, arguments);
}
}
return CustomInstanceFactory.DefaultInstanceFactory.CreateInstance(instanceType, arguments);
} }
public override void Save(System.Xml.XmlWriter writer) public override void Save(System.Xml.XmlWriter writer)

1
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/WpfDesign.XamlDom.csproj

@ -63,6 +63,7 @@
<Compile Include="XamlLoadException.cs" /> <Compile Include="XamlLoadException.cs" />
<Compile Include="XamlObject.cs" /> <Compile Include="XamlObject.cs" />
<Compile Include="XamlParser.cs" /> <Compile Include="XamlParser.cs" />
<Compile Include="XamlParserSettings.cs" />
<Compile Include="XamlProperty.cs" /> <Compile Include="XamlProperty.cs" />
<Compile Include="XamlPropertyInfo.cs" /> <Compile Include="XamlPropertyInfo.cs" />
<Compile Include="XamlTypeFinder.cs" /> <Compile Include="XamlTypeFinder.cs" />

55
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs

@ -25,63 +25,87 @@ namespace ICSharpCode.WpfDesign.XamlDom
/// Parses a XAML document using a stream. /// Parses a XAML document using a stream.
/// </summary> /// </summary>
public static XamlDocument Parse(Stream stream) public static XamlDocument Parse(Stream stream)
{
return Parse(stream, new XamlParserSettings());
}
/// <summary>
/// Parses a XAML document using a TextReader.
/// </summary>
public static XamlDocument Parse(TextReader reader)
{
return Parse(reader, new XamlParserSettings());
}
/// <summary>
/// Parses a XAML document using an XmlReader.
/// </summary>
public static XamlDocument Parse(XmlReader reader)
{
return Parse(reader, new XamlParserSettings());
}
/// <summary>
/// Parses a XAML document using a stream.
/// </summary>
public static XamlDocument Parse(Stream stream, XamlParserSettings settings)
{ {
if (stream == null) if (stream == null)
throw new ArgumentNullException("stream"); throw new ArgumentNullException("stream");
XmlDocument doc = new XmlDocument(); XmlDocument doc = new XmlDocument();
doc.Load(stream); doc.Load(stream);
return Parse(doc); return Parse(doc, settings);
} }
/// <summary> /// <summary>
/// Parses a XAML document using a TextReader. /// Parses a XAML document using a TextReader.
/// </summary> /// </summary>
public static XamlDocument Parse(TextReader reader) public static XamlDocument Parse(TextReader reader, XamlParserSettings settings)
{ {
if (reader == null) if (reader == null)
throw new ArgumentNullException("reader"); throw new ArgumentNullException("reader");
XmlDocument doc = new XmlDocument(); XmlDocument doc = new XmlDocument();
doc.Load(reader); doc.Load(reader);
return Parse(doc); return Parse(doc, settings);
} }
/// <summary> /// <summary>
/// Parses a XAML document using an XmlReader. /// Parses a XAML document using an XmlReader.
/// </summary> /// </summary>
public static XamlDocument Parse(XmlReader reader) public static XamlDocument Parse(XmlReader reader, XamlParserSettings settings)
{ {
if (reader == null) if (reader == null)
throw new ArgumentNullException("reader"); throw new ArgumentNullException("reader");
XmlDocument doc = new XmlDocument(); XmlDocument doc = new XmlDocument();
doc.Load(reader); doc.Load(reader);
return Parse(doc); return Parse(doc, settings);
} }
/// <summary> /// <summary>
/// Creates a XAML document from an existing XmlDocument. /// Creates a XAML document from an existing XmlDocument.
/// </summary> /// </summary>
internal static XamlDocument Parse(XmlDocument document) internal static XamlDocument Parse(XmlDocument document, XamlParserSettings settings)
{ {
if (settings == null)
throw new ArgumentNullException("settings");
if (document == null) if (document == null)
throw new ArgumentNullException("document"); throw new ArgumentNullException("document");
XamlParser p = new XamlParser(); XamlParser p = new XamlParser();
p.settings = settings;
p.document = new XamlDocument(document); p.document = new XamlDocument(document);
p.document.ParseComplete(p.ParseObject(document.DocumentElement)); p.document.ParseComplete(p.ParseObject(document.DocumentElement));
return p.document; return p.document;
} }
#endregion #endregion
XamlDocument document; private XamlParser() { }
XamlTypeFinder typeFinder;
private XamlParser() XamlDocument document;
{ XamlParserSettings settings;
typeFinder = XamlTypeFinder.CreateWpfTypeFinder();
}
Type FindType(string namespaceUri, string localName) Type FindType(string namespaceUri, string localName)
{ {
Type elementType = typeFinder.GetType(namespaceUri, localName); Type elementType = settings.TypeFinder.GetType(namespaceUri, localName);
if (elementType == null) if (elementType == null)
throw new XamlLoadException("Cannot find type " + localName + " in " + namespaceUri); throw new XamlLoadException("Cannot find type " + localName + " in " + namespaceUri);
return elementType; return elementType;
@ -95,12 +119,15 @@ namespace ICSharpCode.WpfDesign.XamlDom
return attribute.OwnerElement.NamespaceURI; return attribute.OwnerElement.NamespaceURI;
} }
readonly static object[] emptyObjectArray = new object[0];
XmlSpace currentXmlSpace = XmlSpace.None; XmlSpace currentXmlSpace = XmlSpace.None;
XamlObject ParseObject(XmlElement element) XamlObject ParseObject(XmlElement element)
{ {
Type elementType = FindType(element.NamespaceURI, element.LocalName); Type elementType = FindType(element.NamespaceURI, element.LocalName);
object instance = Activator.CreateInstance(elementType); //object instance = Activator.CreateInstance(elementType);
object instance = settings.CreateInstanceCallback(elementType, emptyObjectArray);
XamlObject obj = new XamlObject(document, element, elementType, instance); XamlObject obj = new XamlObject(document, element, elementType, instance);
ISupportInitialize iSupportInitializeInstance = instance as ISupportInitialize; ISupportInitialize iSupportInitializeInstance = instance as ISupportInitialize;

49
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParserSettings.cs

@ -0,0 +1,49 @@
// <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.XamlDom
{
/// <summary>
/// Delegate used for XamlParserSettings.CreateInstanceCallback.
/// </summary>
public delegate object CreateInstanceCallback(Type type, object[] arguments);
/// <summary>
/// Settings used for the XamlParser.
/// </summary>
public sealed class XamlParserSettings
{
CreateInstanceCallback _createInstanceCallback = Activator.CreateInstance;
XamlTypeFinder _typeFinder = XamlTypeFinder.CreateWpfTypeFinder();
/// <summary>
/// Gets/Sets the method used to create object instances.
/// </summary>
public CreateInstanceCallback CreateInstanceCallback {
get { return _createInstanceCallback; }
set {
if (value == null)
throw new ArgumentNullException("value");
_createInstanceCallback = value;
}
}
/// <summary>
/// Gets/Sets the type finder to do type lookup.
/// </summary>
public XamlTypeFinder TypeFinder {
get { return _typeFinder; }
set {
if (value == null)
throw new ArgumentNullException("value");
_typeFinder = value;
}
}
}
}

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Tests/TestHelper.cs

@ -28,7 +28,7 @@ namespace ICSharpCode.WpfDesign.XamlDom.Tests
Debug.WriteLine("Load using own XamlParser:"); Debug.WriteLine("Load using own XamlParser:");
ExampleClass.nextUniqueIndex = 0; ExampleClass.nextUniqueIndex = 0;
TestHelperLog.logBuilder = new StringBuilder(); TestHelperLog.logBuilder = new StringBuilder();
XamlDocument doc = XamlParser.Parse(new XmlTextReader(new StringReader(xaml))); XamlDocument doc = XamlParser.Parse(new StringReader(xaml));
Assert.IsNotNull(doc, "doc is null"); Assert.IsNotNull(doc, "doc is null");
object ownResult = doc.RootInstance; object ownResult = doc.RootInstance;
string ownLog = TestHelperLog.logBuilder.ToString(); string ownLog = TestHelperLog.logBuilder.ToString();

30
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs

@ -108,5 +108,35 @@ namespace ICSharpCode.WpfDesign
} }
} }
#endregion #endregion
#region Manage behavior
Dictionary<Type, object> _behaviorObjects = new Dictionary<Type, object>();
/// <summary>
/// Adds a bevahior extension object to this design item.
/// </summary>
public void AddBehavior(Type bevahiorInterface, object behaviorImplementation)
{
if (bevahiorInterface == null)
throw new ArgumentNullException("bevahiorInterface");
if (behaviorImplementation == null)
throw new ArgumentNullException("behaviorImplementation");
_behaviorObjects.Add(bevahiorInterface, behaviorImplementation);
}
/// <summary>
/// Gets a bevahior extension object from the design item.
/// </summary>
/// <returns>The behavior object, or null if it was not found.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
public T GetBehavior<T>() where T : class
{
object obj;
_behaviorObjects.TryGetValue(typeof(T), out obj);
return (T)obj;
}
#endregion
} }
} }

1
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/BehaviorExtension.cs

@ -51,6 +51,7 @@ namespace ICSharpCode.WpfDesign.Extensions
/// <summary> /// <summary>
/// Is called after the ExtendedItem was set. /// Is called after the ExtendedItem was set.
/// Override this method to register your behavior with the item.
/// </summary> /// </summary>
protected virtual void OnInitialized() protected virtual void OnInitialized()
{ {

63
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/CustomInstanceFactory.cs

@ -0,0 +1,63 @@
// <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>
/// A special kind of extension that is used to create instances of objects when loading XAML inside
/// the designer.
/// </summary>
/// <remarks>
/// CustomInstanceFactory in Cider: http://blogs.msdn.com/jnak/archive/2006/04/10/572241.aspx
/// </remarks>
[ExtensionServer(typeof(NeverApplyExtensionsExtensionServer))]
public class CustomInstanceFactory : Extension
{
/// <summary>
/// Gets a default instance factory that uses Activator.CreateInstance to create instances.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly CustomInstanceFactory DefaultInstanceFactory = new CustomInstanceFactory();
/// <summary>
/// Creates a new CustomInstanceFactory instance.
/// </summary>
protected CustomInstanceFactory()
{
}
/// <summary>
/// Creates an instance of the specified type, passing the specified arguments to its constructor.
/// </summary>
public virtual object CreateInstance(Type type, params object[] arguments)
{
return Activator.CreateInstance(type, arguments);
}
}
// An extension server that never applies its extensions - used for special extensions
// like CustomInstanceFactory
sealed class NeverApplyExtensionsExtensionServer : ExtensionServer
{
public override bool ShouldApplyExtensions(DesignItem extendedItem)
{
return false;
}
public override Extension CreateExtension(Type extensionType, DesignItem extendedItem)
{
throw new NotImplementedException();
}
public override void RemoveExtension(Extension extension)
{
throw new NotImplementedException();
}
}
}

10
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/ExtensionManager.cs

@ -83,6 +83,16 @@ namespace ICSharpCode.WpfDesign.Extensions
} }
return result; return result;
} }
/// <summary>
/// Gets all the types of all extensions that are applied to the specified item type.
/// </summary>
public IEnumerable<Type> GetExtensionTypes(Type extendedItemType)
{
foreach (ExtensionEntry entry in GetExtensionEntries(extendedItemType)) {
yield return entry.ExtensionType;
}
}
#endregion #endregion
#region Create Extensions #region Create Extensions

11
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Tools.cs

@ -41,6 +41,17 @@ namespace ICSharpCode.WpfDesign
Highest Highest
} }
/// <summary>
/// Interface for behavior extensions that specifies the input layer of the extended component.
/// </summary>
public interface IProvideComponentInputHandlingLayer
{
/// <summary>
/// Gets the input handling layer of the component.
/// </summary>
InputHandlingLayer InputLayer { get; }
}
/// <summary> /// <summary>
/// Describes a tool that can handle input on the design surface. /// Describes a tool that can handle input on the design surface.
/// Modelled after the description on http://urbanpotato.net/Default.aspx/document/2300 /// Modelled after the description on http://urbanpotato.net/Default.aspx/document/2300

1
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj

@ -62,6 +62,7 @@
<Compile Include="Configuration\AssemblyInfo.cs" /> <Compile Include="Configuration\AssemblyInfo.cs" />
<Compile Include="DesignerException.cs" /> <Compile Include="DesignerException.cs" />
<Compile Include="Extensions\BehaviorExtension.cs" /> <Compile Include="Extensions\BehaviorExtension.cs" />
<Compile Include="Extensions\CustomInstanceFactory.cs" />
<Compile Include="Extensions\Extension.cs" /> <Compile Include="Extensions\Extension.cs" />
<Compile Include="Extensions\ExtensionForAttribute.cs" /> <Compile Include="Extensions\ExtensionForAttribute.cs" />
<Compile Include="Extensions\ExtensionManager.cs" /> <Compile Include="Extensions\ExtensionManager.cs" />

Loading…
Cancel
Save