Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3609 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
160 changed files with 14978 additions and 565 deletions
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
<Default:ToolboxData xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
xmlns:Default="clr-namespace:ICSharpCode.WpfDesign.Designer;assembly=ICSharpCode.WpfDesign.Designer" |
||||
xmlns:Forms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"> |
||||
<Default:ToolboxItem Type="Button" |
||||
FormsType="{x:Type Forms:Button}" /> |
||||
<Default:ToolboxItem Type="CheckBox" |
||||
FormsType="{x:Type Forms:CheckBox}" /> |
||||
<Default:ToolboxItem Type="ComboBox" |
||||
FormsType="{x:Type Forms:ComboBox}" /> |
||||
<Default:ToolboxItem Type="Label" |
||||
FormsType="{x:Type Forms:Label}" /> |
||||
<Default:ToolboxItem Type="TextBox" |
||||
FormsType="{x:Type Forms:TextBox}" /> |
||||
<Default:ToolboxItem Type="RadioButton" |
||||
FormsType="{x:Type Forms:RadioButton}" /> |
||||
<Default:ToolboxItem Type="Canvas" |
||||
FormsType="{x:Type Forms:Panel}" /> |
||||
<Default:ToolboxItem Type="Grid" |
||||
FormsType="{x:Type Forms:TableLayoutPanel}" /> |
||||
<Default:ToolboxItem Type="Border" |
||||
FormsType="{x:Type Forms:Panel}" /> |
||||
<Default:ToolboxItem Type="DockPanel" |
||||
FormsType="{x:Type Forms:Panel}" /> |
||||
<Default:ToolboxItem Type="Expander" |
||||
FormsType="{x:Type Forms:Panel}" /> |
||||
<Default:ToolboxItem Type="GroupBox" |
||||
FormsType="{x:Type Forms:GroupBox}" /> |
||||
<Default:ToolboxItem Type="Image" |
||||
FormsType="{x:Type Forms:PictureBox}" /> |
||||
<Default:ToolboxItem Type="InkCanvas" |
||||
FormsType="{x:Type Forms:Panel}" /> |
||||
<Default:ToolboxItem Type="ListBox" |
||||
FormsType="{x:Type Forms:ListBox}" /> |
||||
<Default:ToolboxItem Type="Menu" |
||||
FormsType="{x:Type Forms:MenuStrip}" /> |
||||
<Default:ToolboxItem Type="PasswordBox" |
||||
FormsType="{x:Type Forms:TextBox}" /> |
||||
<Default:ToolboxItem Type="ProgressBar" |
||||
FormsType="{x:Type Forms:ProgressBar}" /> |
||||
<Default:ToolboxItem Type="RichTextBox" |
||||
FormsType="{x:Type Forms:RichTextBox}" /> |
||||
<Default:ToolboxItem Type="ScrollViewer" |
||||
FormsType="{x:Type Forms:VScrollBar}" /> |
||||
<Default:ToolboxItem Type="Slider" |
||||
FormsType="{x:Type Forms:TrackBar}" /> |
||||
<Default:ToolboxItem Type="StackPanel" |
||||
FormsType="{x:Type Forms:Panel}" /> |
||||
<Default:ToolboxItem Type="TabControl" |
||||
FormsType="{x:Type Forms:TabControl}" /> |
||||
<Default:ToolboxItem Type="ToolBar" |
||||
FormsType="{x:Type Forms:ToolStrip}" /> |
||||
<Default:ToolboxItem Type="TreeView" |
||||
FormsType="{x:Type Forms:TreeView}" /> |
||||
<Default:ToolboxItem Type="Viewbox" |
||||
FormsType="{x:Type Forms:Panel}" /> |
||||
<Default:ToolboxItem Type="Viewport3D" |
||||
FormsType="{x:Type Forms:Panel}" /> |
||||
<Default:ToolboxItem Type="WrapPanel" |
||||
FormsType="{x:Type Forms:FlowLayoutPanel}" /> |
||||
</Default:ToolboxData> |
@ -1,23 +1,23 @@
@@ -1,23 +1,23 @@
|
||||
<UserControl |
||||
x:Class="ICSharpCode.XamlDesigner.DocumentView" |
||||
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
xmlns:Integration="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration" |
||||
xmlns:TextEditor="clr-namespace:ICSharpCode.TextEditor;assembly=ICSharpCode.TextEditor" |
||||
xmlns:Default="clr-namespace:ICSharpCode.XamlDesigner" |
||||
xmlns:DesignerControls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls;assembly=ICSharpCode.WpfDesign.Designer" |
||||
> |
||||
|
||||
<UserControl x:Class="ICSharpCode.XamlDesigner.DocumentView" |
||||
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
xmlns:Integration="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration" |
||||
xmlns:Default="clr-namespace:ICSharpCode.XamlDesigner" |
||||
xmlns:Designer="clr-namespace:ICSharpCode.WpfDesign.Designer;assembly=ICSharpCode.WpfDesign.Designer" |
||||
xmlns:DesignerControls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls;assembly=ICSharpCode.WpfDesign.Designer"> |
||||
|
||||
<DockPanel> |
||||
<DesignerControls:EnumBar Value="{Binding Mode}" |
||||
DockPanel.Dock="Bottom"/> |
||||
DockPanel.Dock="Bottom" /> |
||||
<Grid> |
||||
<Integration:WindowsFormsHost Visibility="{Binding InXamlMode, Converter={StaticResource CollapsedWhenFalse}}"> |
||||
<TextEditor:TextEditorControl x:Name="uxTextEditor" /> |
||||
<Default:TextEditorWithoutUndo x:Name="uxTextEditor" /> |
||||
</Integration:WindowsFormsHost> |
||||
<ContentPresenter Content="{Binding DesignSurface}" |
||||
Visibility="{Binding InDesignMode, Converter={StaticResource CollapsedWhenFalse}}"/> |
||||
|
||||
<Designer:DesignSurface x:Name="uxDesignSurface" |
||||
Context="{Binding Context}" |
||||
Visibility="{Binding InDesignMode, Converter={StaticResource CollapsedWhenFalse}}" /> |
||||
</Grid> |
||||
</DockPanel> |
||||
|
||||
|
||||
</UserControl> |
After Width: | Height: | Size: 470 B |
After Width: | Height: | Size: 537 B |
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
using System.Windows; |
||||
|
||||
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] |
@ -0,0 +1,110 @@
@@ -0,0 +1,110 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:2.0.50727.3053
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ICSharpCode.XamlDesigner.Properties { |
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")] |
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { |
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); |
||||
|
||||
public static Settings Default { |
||||
get { |
||||
return defaultInstance; |
||||
} |
||||
} |
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()] |
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||
[global::System.Configuration.DefaultSettingValueAttribute("0,0,0,0")] |
||||
public global::System.Windows.Rect MainWindowRect { |
||||
get { |
||||
return ((global::System.Windows.Rect)(this["MainWindowRect"])); |
||||
} |
||||
set { |
||||
this["MainWindowRect"] = value; |
||||
} |
||||
} |
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()] |
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||
[global::System.Configuration.DefaultSettingValueAttribute(@"<DockingManager>
|
||||
<ResizingPanel Orientation=""Horizontal""> |
||||
<ResizingPanel ResizeWidth=""200"" Orientation=""Vertical""> |
||||
<DockablePane ResizeHeight=""441.36166666666668"" Anchor=""Left""> |
||||
<DockableContent Name=""content1"" AutoHide=""false"" /> |
||||
</DockablePane> |
||||
<DockablePane ResizeWidth=""200"" Anchor=""Left""> |
||||
<DockableContent Name=""content2"" AutoHide=""false"" /> |
||||
</DockablePane> |
||||
</ResizingPanel> |
||||
<ResizingPanel Orientation=""Vertical""> |
||||
<DocumentPanePlaceHolder /> |
||||
<DockablePane ResizeHeight=""138"" Anchor=""Bottom""> |
||||
<DockableContent Name=""content3"" AutoHide=""false"" /> |
||||
</DockablePane> |
||||
</ResizingPanel> |
||||
<DockablePane ResizeWidth=""271"" Anchor=""Right""> |
||||
<DockableContent Name=""content4"" AutoHide=""false"" /> |
||||
</DockablePane> |
||||
</ResizingPanel> |
||||
<Hidden /> |
||||
<Windows /> |
||||
</DockingManager>")]
|
||||
public string AvalonDockLayout { |
||||
get { |
||||
return ((string)(this["AvalonDockLayout"])); |
||||
} |
||||
set { |
||||
this["AvalonDockLayout"] = value; |
||||
} |
||||
} |
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()] |
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||
public global::System.Collections.Specialized.StringCollection RecentFiles { |
||||
get { |
||||
return ((global::System.Collections.Specialized.StringCollection)(this["RecentFiles"])); |
||||
} |
||||
set { |
||||
this["RecentFiles"] = value; |
||||
} |
||||
} |
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()] |
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||
[global::System.Configuration.DefaultSettingValueAttribute(@"<?xml version=""1.0"" encoding=""utf-16""?>
|
||||
<ArrayOfString xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
|
||||
<string>%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.dll</string> |
||||
</ArrayOfString>")]
|
||||
public global::System.Collections.Specialized.StringCollection AssemblyList { |
||||
get { |
||||
return ((global::System.Collections.Specialized.StringCollection)(this["AssemblyList"])); |
||||
} |
||||
set { |
||||
this["AssemblyList"] = value; |
||||
} |
||||
} |
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()] |
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||
[global::System.Configuration.DefaultSettingValueAttribute("Maximized")] |
||||
public global::System.Windows.WindowState MainWindowState { |
||||
get { |
||||
return ((global::System.Windows.WindowState)(this["MainWindowState"])); |
||||
} |
||||
set { |
||||
this["MainWindowState"] = value; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
<?xml version='1.0' encoding='utf-8'?> |
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="ICSharpCode.XamlDesigner.Properties" GeneratedClassName="Settings"> |
||||
<Profiles /> |
||||
<Settings> |
||||
<Setting Name="MainWindowRect" Type="System.Windows.Rect" Scope="User"> |
||||
<Value Profile="(Default)">0,0,0,0</Value> |
||||
</Setting> |
||||
<Setting Name="AvalonDockLayout" Type="System.String" Scope="User"> |
||||
<Value Profile="(Default)"><DockingManager> |
||||
<ResizingPanel Orientation="Horizontal"> |
||||
<ResizingPanel ResizeWidth="200" Orientation="Vertical"> |
||||
<DockablePane ResizeHeight="441.36166666666668" Anchor="Left"> |
||||
<DockableContent Name="content1" AutoHide="false" /> |
||||
</DockablePane> |
||||
<DockablePane ResizeWidth="200" Anchor="Left"> |
||||
<DockableContent Name="content2" AutoHide="false" /> |
||||
</DockablePane> |
||||
</ResizingPanel> |
||||
<ResizingPanel Orientation="Vertical"> |
||||
<DocumentPanePlaceHolder /> |
||||
<DockablePane ResizeHeight="138" Anchor="Bottom"> |
||||
<DockableContent Name="content3" AutoHide="false" /> |
||||
</DockablePane> |
||||
</ResizingPanel> |
||||
<DockablePane ResizeWidth="271" Anchor="Right"> |
||||
<DockableContent Name="content4" AutoHide="false" /> |
||||
</DockablePane> |
||||
</ResizingPanel> |
||||
<Hidden /> |
||||
<Windows /> |
||||
</DockingManager></Value> |
||||
</Setting> |
||||
<Setting Name="RecentFiles" Type="System.Collections.Specialized.StringCollection" Scope="User"> |
||||
<Value Profile="(Default)" /> |
||||
</Setting> |
||||
<Setting Name="AssemblyList" Type="System.Collections.Specialized.StringCollection" Scope="User"> |
||||
<Value Profile="(Default)"><?xml version="1.0" encoding="utf-16"?> |
||||
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
||||
<string>%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.dll</string> |
||||
</ArrayOfString></Value> |
||||
</Setting> |
||||
<Setting Name="MainWindowState" Type="System.Windows.WindowState" Scope="User"> |
||||
<Value Profile="(Default)">Maximized</Value> |
||||
</Setting> |
||||
</Settings> |
||||
</SettingsFile> |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> |
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> |
||||
<security> |
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> |
||||
<!-- UAC Manifest Options |
||||
If you want to change the Windows User Account Control level replace the |
||||
requestedExecutionLevel node with one of the following. |
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" /> |
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> |
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" /> |
||||
|
||||
If you want to utilize File and Registry Virtualization for backward |
||||
compatibility then delete the requestedExecutionLevel node. |
||||
--> |
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" /> |
||||
</requestedPrivileges> |
||||
</security> |
||||
</trustInfo> |
||||
|
||||
<dependency> |
||||
<dependentAssembly> |
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity> |
||||
</dependentAssembly> |
||||
</dependency> |
||||
|
||||
</asmv1:assembly> |
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
<Window xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
Width="524" |
||||
Height="385"> |
||||
<ContentControl.Content> |
||||
<Grid> |
||||
<Panel.Children /> |
||||
</Grid> |
||||
</ContentControl.Content> |
||||
</Window> |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using ICSharpCode.WpfDesign.Designer.OutlineView; |
||||
|
||||
namespace ICSharpCode.XamlDesigner |
||||
{ |
||||
class ToolboxTreeView : DragTreeView |
||||
{ |
||||
protected override bool CanInsert(DragTreeViewItem target, DragTreeViewItem[] items, DragTreeViewItem after, bool copy) |
||||
{ |
||||
return base.CanInsert(target, items, after, copy); |
||||
} |
||||
|
||||
protected override void Insert(DragTreeViewItem target, DragTreeViewItem[] items, DragTreeViewItem after, bool copy) |
||||
{ |
||||
base.Insert(target, items, after, copy); |
||||
} |
||||
|
||||
protected override void Remove(DragTreeViewItem target, DragTreeViewItem item) |
||||
{ |
||||
base.Remove(target, item); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?> |
||||
<configuration> |
||||
<configSections> |
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > |
||||
<section name="ICSharpCode.XamlDesigner.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" /> |
||||
</sectionGroup> |
||||
</configSections> |
||||
<userSettings> |
||||
<ICSharpCode.XamlDesigner.Properties.Settings> |
||||
<setting name="MainWindowRect" serializeAs="String"> |
||||
<value>0,0,0,0</value> |
||||
</setting> |
||||
<setting name="AvalonDockLayout" serializeAs="String"> |
||||
<value><DockingManager> |
||||
<ResizingPanel Orientation="Horizontal"> |
||||
<ResizingPanel ResizeWidth="200" Orientation="Vertical"> |
||||
<DockablePane ResizeHeight="441.36166666666668" Anchor="Left"> |
||||
<DockableContent Name="content1" AutoHide="false" /> |
||||
</DockablePane> |
||||
<DockablePane ResizeWidth="200" Anchor="Left"> |
||||
<DockableContent Name="content2" AutoHide="false" /> |
||||
</DockablePane> |
||||
</ResizingPanel> |
||||
<ResizingPanel Orientation="Vertical"> |
||||
<DocumentPanePlaceHolder /> |
||||
<DockablePane ResizeHeight="138" Anchor="Bottom"> |
||||
<DockableContent Name="content3" AutoHide="false" /> |
||||
</DockablePane> |
||||
</ResizingPanel> |
||||
<DockablePane ResizeWidth="271" Anchor="Right"> |
||||
<DockableContent Name="content4" AutoHide="false" /> |
||||
</DockablePane> |
||||
</ResizingPanel> |
||||
<Hidden /> |
||||
<Windows /> |
||||
</DockingManager></value> |
||||
</setting> |
||||
<setting name="AssemblyList" serializeAs="Xml"> |
||||
<value> |
||||
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
||||
<string>%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.dll</string> |
||||
</ArrayOfString> |
||||
</value> |
||||
</setting> |
||||
<setting name="MainWindowState" serializeAs="String"> |
||||
<value>Maximized</value> |
||||
</setting> |
||||
</ICSharpCode.XamlDesigner.Properties.Settings> |
||||
</userSettings> |
||||
</configuration> |
@ -0,0 +1,197 @@
@@ -0,0 +1,197 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using NUnit.Framework; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Media; |
||||
using System.Windows.Data; |
||||
using System.Windows; |
||||
using System.Windows.Documents; |
||||
using System.Xml.Linq; |
||||
using System.Windows.Markup; |
||||
using ICSharpCode.WpfDesign.Designer.XamlBackend; |
||||
|
||||
namespace ICSharpCode.Xaml.Tests |
||||
{ |
||||
[TestFixture] |
||||
public class EditingTests |
||||
{ |
||||
DefaultWpfProject project = new DefaultWpfProject(); |
||||
XamlDocument document; |
||||
|
||||
void Check(string s) |
||||
{ |
||||
var doc1 = XDocument.Parse(EasyDocument(s)); |
||||
foreach (var e in doc1.Root.DescendantsAndSelf()) { |
||||
e.Name = XamlConstants.Presentation2007Namespace + e.Name.LocalName; |
||||
} |
||||
|
||||
Assert.IsTrue(XNode.DeepEquals(doc1, document.XmlDocument)); |
||||
|
||||
// some tests incorrect from instance point of view
|
||||
object officialInstance = null; |
||||
try { |
||||
officialInstance = XamlReader.Parse(document.XmlDocument.ToString()); |
||||
} |
||||
catch { |
||||
return; |
||||
} |
||||
|
||||
var myResult = XamlWriter.Save(document.Root.Instance); |
||||
var officialResult = XamlWriter.Save(officialInstance); |
||||
|
||||
Assert.AreEqual(myResult, officialResult); |
||||
} |
||||
|
||||
string EasyDocument(string s) |
||||
{ |
||||
var index = s.IndexOfAny(new[] { ' ', '/', '>' }); |
||||
return s.Insert(index, string.Format(" xmlns='{0}' xmlns:x='{1}' ", |
||||
XamlConstants.Presentation2007Namespace, XamlConstants.XamlNamespace)); |
||||
} |
||||
|
||||
[Test] |
||||
public void Test1() |
||||
{ |
||||
document = project.CreateDocument(new Button()); |
||||
ObjectNode button = document.Root; |
||||
|
||||
Check("<Button/>"); |
||||
|
||||
button.Property("Width").Set(100); |
||||
Check("<Button Width='100'/>"); |
||||
|
||||
button.Property("Width").Reset(); |
||||
Check("<Button/>"); |
||||
|
||||
button.Property(Button.WidthProperty).Set(100); |
||||
Check("<Button Width='100'/>"); |
||||
|
||||
button.Property(Button.WidthProperty).Reset(); |
||||
Check("<Button/>"); |
||||
|
||||
button.Content.Set("Label"); |
||||
Check("<Button Content='Label'/>"); |
||||
|
||||
button.Content.Set(new Border()); |
||||
Check("<Button><Border/></Button>"); |
||||
button.Content.Reset(); |
||||
|
||||
button.Property(Button.BackgroundProperty).Set(new LinearGradientBrush()); |
||||
Check("<Button><Button.Background><LinearGradientBrush/></Button.Background></Button>"); |
||||
button.Property(Button.BackgroundProperty).Reset(); |
||||
|
||||
button.Property(Canvas.LeftProperty).Set(100); |
||||
Check("<Button Canvas.Left='100'/>"); |
||||
button.Property(Canvas.LeftProperty).Reset(); |
||||
|
||||
var binding = button.Content.SetObject(new Binding()); |
||||
Check("<Button Content='{Binding}'/>"); |
||||
|
||||
binding.Property("ElementName").Set("e1"); |
||||
Check("<Button Content='{Binding ElementName=e1}'/>"); |
||||
|
||||
binding.Property("Mode").Set(BindingMode.TwoWay); |
||||
Check("<Button Content='{Binding ElementName=e1, Mode=TwoWay}'/>"); |
||||
|
||||
var staticResource = binding.Property("Converter").SetObject(new StaticResourceExtension()); |
||||
staticResource.Property("ResourceKey").Set("Converter1"); |
||||
Check("<Button Content='{Binding ElementName=e1, Mode=TwoWay, Converter={StaticResource Converter1}}'/>"); |
||||
button.Content.Reset(); |
||||
|
||||
binding = button.Content.SetObject("{Binding Some1}"); |
||||
Check("<Button Content='{Binding Some1}'/>"); |
||||
|
||||
binding.Property("Source").Set(new Button()); |
||||
Check("<Button><Binding Path='Some1'><Binding.Source><Button/></Binding.Source></Binding></Button>"); |
||||
|
||||
binding.Property("Source").Reset(); |
||||
Check("<Button Content='{Binding Some1}'/>"); |
||||
|
||||
binding.Remove(); |
||||
Check("<Button/>"); |
||||
|
||||
button.Property("Resources").Add("brush1", Brushes.Red); |
||||
Check("<Button><Button.Resources><Brush x:Key='brush1'>Red</Brush></Button.Resources></Button>"); |
||||
|
||||
button.Property("Resources").Reset(); |
||||
Check("<Button/>"); |
||||
} |
||||
|
||||
[Test] |
||||
public void Test2() |
||||
{ |
||||
document = project.CreateDocument(new TextBlock()); |
||||
ObjectNode textBlock = document.Root; |
||||
|
||||
Check("<TextBlock/>"); |
||||
|
||||
textBlock.Content.Add("text1"); |
||||
Check("<TextBlock>text1</TextBlock>"); |
||||
|
||||
textBlock.Content.Add("text2"); |
||||
Check("<TextBlock>text1text2</TextBlock>"); |
||||
|
||||
var bold = textBlock.Content.AddObject(new Bold()); |
||||
bold.Content.Set("bold1"); |
||||
textBlock.Content.Add("text3"); |
||||
Check("<TextBlock>text1text2<Bold>bold1</Bold>text3</TextBlock>"); |
||||
|
||||
//var bold = textBlock.Content.AddObject(new Bold());
|
||||
//bold.Content.Set("bold1");
|
||||
//textBlock.Content.Add(" text3 ");
|
||||
//Check("<TextBlock xml:space='preserve'>text1text2<Bold>bold1</Bold> text3 </TextBlock>");
|
||||
|
||||
//bold.Remove();
|
||||
//Check("<TextBlock>text1text2 text3 </TextBlock>");
|
||||
|
||||
//textBlock.Content.Reset();
|
||||
//Check("<TextBlock/>");
|
||||
} |
||||
|
||||
[Test] |
||||
public void Test3() |
||||
{ |
||||
document = project.CreateDocument(new CheckBox()); |
||||
var checkBox = document.Root; |
||||
document.Root = null; |
||||
Assert.IsTrue(document.XmlDocument.Root == null); |
||||
|
||||
document.Root = checkBox; |
||||
Check("<CheckBox/>"); |
||||
|
||||
document.Parse(EasyDocument("<Slider/>")); |
||||
Check("<Slider/>"); |
||||
|
||||
var canvas = document.CreateObject(new Canvas()); |
||||
canvas.Property("Width").Set(100); |
||||
document.Root = canvas; |
||||
Check("<Canvas Width='100'/>"); |
||||
canvas.Property("Width").Reset(); |
||||
|
||||
var button1 = canvas.Content.AddObject(new Button()); |
||||
canvas.Content.Add(new Button()); |
||||
button1.Remove(); |
||||
Check("<Canvas><Button/></Canvas>"); |
||||
} |
||||
|
||||
//[Test]
|
||||
//public void Test4()
|
||||
//{
|
||||
// document = project.CreateDocument(new Style());
|
||||
// var style = document.Root;
|
||||
// var setter = style.Content.AddObject(new Setter());
|
||||
// setter.Property("Property").Set("Background");
|
||||
//}
|
||||
|
||||
[Test] |
||||
public void Test5() |
||||
{ |
||||
document = project.CreateDocument(new Button()); |
||||
var button = document.Root; |
||||
Assert.AreEqual(button.Property(Button.HorizontalAlignmentProperty).ValueOnInstance, |
||||
new Button().HorizontalAlignment); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,85 @@
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<ProductVersion>9.0.30729</ProductVersion> |
||||
<SchemaVersion>2.0</SchemaVersion> |
||||
<ProjectGuid>{EDF67E30-F45F-40C5-8B68-4A22FFD02A2E}</ProjectGuid> |
||||
<OutputType>Library</OutputType> |
||||
<AppDesignerFolder>Properties</AppDesignerFolder> |
||||
<RootNamespace>ICSharpCode.Xaml.Tests</RootNamespace> |
||||
<AssemblyName>ICSharpCode.Xaml.Tests</AssemblyName> |
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> |
||||
<FileAlignment>512</FileAlignment> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>full</DebugType> |
||||
<Optimize>false</Optimize> |
||||
<OutputPath>..\..\..\..\..\bin\UnitTests\</OutputPath> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
<ErrorReport>prompt</ErrorReport> |
||||
<WarningLevel>4</WarningLevel> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
||||
<DebugType>pdbonly</DebugType> |
||||
<Optimize>true</Optimize> |
||||
<OutputPath>bin\Release\</OutputPath> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
<ErrorReport>prompt</ErrorReport> |
||||
<WarningLevel>4</WarningLevel> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="nunit.framework, Version=2.4.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" /> |
||||
<Reference Include="PresentationCore"> |
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="PresentationFramework"> |
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Core"> |
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System.Xml.Linq"> |
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System.Data.DataSetExtensions"> |
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System.Data" /> |
||||
<Reference Include="System.Xml" /> |
||||
<Reference Include="WindowsBase"> |
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
||||
</Reference> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="..\..\..\..\Main\GlobalAssemblyInfo.cs"> |
||||
<Link>Properties\GlobalAssemblyInfo.cs</Link> |
||||
</Compile> |
||||
<Compile Include="EditingTests.cs" /> |
||||
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<None Include="app.config" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ProjectReference Include="..\..\..\DisplayBindings\WpfDesign\WpfDesign.Designer\WpfDesign.Designer.csproj"> |
||||
<Project>{78CC29AC-CC79-4355-B1F2-97936DF198AC}</Project> |
||||
<Name>WpfDesign.Designer</Name> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\Xaml\Xaml.csproj"> |
||||
<Project>{B4E5C965-7BB9-4AE9-85FB-C47480B879AD}</Project> |
||||
<Name>Xaml</Name> |
||||
</ProjectReference> |
||||
</ItemGroup> |
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
||||
Other similar extension points exist, see Microsoft.Common.targets. |
||||
<Target Name="BeforeBuild"> |
||||
</Target> |
||||
<Target Name="AfterBuild"> |
||||
</Target> |
||||
--> |
||||
</Project> |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?> |
||||
<configuration> |
||||
<configSections> |
||||
<sectionGroup name="NUnit"> |
||||
<section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/> |
||||
</sectionGroup> |
||||
</configSections> |
||||
<NUnit> |
||||
<TestRunner> |
||||
<add key="ApartmentState" value="STA" /> |
||||
</TestRunner> |
||||
</NUnit> |
||||
</configuration> |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public enum AllowedLocation |
||||
{ |
||||
Any, AttributeOnly, None |
||||
} |
||||
} |
@ -0,0 +1,60 @@
@@ -0,0 +1,60 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision: 3509 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.Collections; |
||||
using System.ComponentModel; |
||||
using System.Globalization; |
||||
using System.Reflection; |
||||
using System.Windows; |
||||
using System.Windows.Markup; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
/// <summary>
|
||||
/// Static class containing helper methods to work with collections (like the XamlParser does)
|
||||
/// </summary>
|
||||
public static class CollectionSupport |
||||
{ |
||||
/// <summary>
|
||||
/// Gets if the type is considered a collection in XAML.
|
||||
/// </summary>
|
||||
public static bool IsCollectionType(Type type) |
||||
{ |
||||
return typeof(IList).IsAssignableFrom(type) |
||||
|| type.IsArray |
||||
|| typeof(IAddChild).IsAssignableFrom(type) |
||||
|| typeof(ResourceDictionary).IsAssignableFrom(type); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if the collection type <paramref name="col"/> can accepts items of type
|
||||
/// <paramref name="item"/>.
|
||||
/// </summary>
|
||||
public static bool CanCollectionAdd(Type col, Type item) |
||||
{ |
||||
var e = col.GetInterface("IEnumerable`1"); |
||||
if (e != null && e.IsGenericType) { |
||||
var a = e.GetGenericArguments()[0]; |
||||
return a.IsAssignableFrom(item); |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if the collection type <paramref name="col"/> can accept the specified items.
|
||||
/// </summary>
|
||||
public static bool CanCollectionAdd(Type col, IEnumerable items) |
||||
{ |
||||
foreach (var item in items) { |
||||
if (!CanCollectionAdd(col, item.GetType())) return false; |
||||
} |
||||
return true; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class Constructor |
||||
{ |
||||
public XamlType[] Arguments; |
||||
public XamlMember[] CorrespondingMembers; |
||||
} |
||||
} |
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class DefaultXamlMember : XamlMember |
||||
{ |
||||
public override string Name |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlType OwnerType |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlType ValueType |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsReadOnly |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsStatic |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsAttachable |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlType TargetType |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override AllowedLocation AllowedLocation |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsEvent |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsDirective |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override T GetAttribute<T>() |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public override bool HasTextSyntax |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,140 @@
@@ -0,0 +1,140 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class DefaultXamlType : XamlType |
||||
{ |
||||
public override string Name |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsDefaultConstructible |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsNullable |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override IEnumerable<XamlMember> Members |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlMember ContentProperty |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlMember DictionaryKeyProperty |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlMember NameProperty |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlMember XmlLangProperty |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool TrimSurroundingWhitespace |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsWhitespaceSignificantCollection |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsCollection |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsDictionary |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override IEnumerable<XamlType> AllowedTypes |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override IEnumerable<XamlType> AllowedKeyTypes |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsXData |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsNameScope |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override IEnumerable<Constructor> Constructors |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlType ReturnValueType |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override string Namespace |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlAssembly Assembly |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlMember Member(string name) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public override IEnumerable<XamlType> ContentWrappers |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool HasTextSyntax |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override Type SystemType |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsAssignableFrom(XamlType type) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public override T GetAttribute<T>() |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Xml.Linq; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class Directive |
||||
{ |
||||
static Directive() |
||||
{ |
||||
Name = CreateXamlDirective("Name"); |
||||
Key = CreateXamlDirective("Key"); |
||||
Uid = CreateXamlDirective("Uid"); |
||||
Class = CreateXamlDirective("Class"); |
||||
ClassModifier = CreateXamlDirective("ClassModifier"); |
||||
FieldModifier = CreateXamlDirective("FieldModifier"); |
||||
TypeArguments = CreateXamlDirective("TypeArguments"); |
||||
XmlLang = CreateDirective(XNamespace.Xml + "lang"); |
||||
XmlSpace = CreateDirective(XNamespace.Xml + "space"); |
||||
} |
||||
|
||||
public static XamlMember Name; |
||||
public static XamlMember Key; |
||||
public static XamlMember Uid; |
||||
public static XamlMember Class; |
||||
public static XamlMember ClassModifier; |
||||
public static XamlMember FieldModifier; |
||||
public static XamlMember TypeArguments; |
||||
public static XamlMember XmlLang; |
||||
public static XamlMember XmlSpace; |
||||
|
||||
static XamlMember CreateXamlDirective(string name) |
||||
{ |
||||
return CreateDirective(XamlConstants.XamlNamespace + name); |
||||
} |
||||
|
||||
static XamlMember CreateDirective(XName name) |
||||
{ |
||||
var result = new IntristicMember(name.LocalName); |
||||
directiveFromName[name] = result; |
||||
nameFromDirective[result] = name; |
||||
return result; |
||||
} |
||||
|
||||
static Dictionary<XName, XamlMember> directiveFromName = new Dictionary<XName, XamlMember>(); |
||||
static Dictionary<XamlMember, XName> nameFromDirective = new Dictionary<XamlMember, XName>(); |
||||
|
||||
public static XamlMember GetDirective(XName name) |
||||
{ |
||||
XamlMember result; |
||||
if (directiveFromName.TryGetValue(name, out result)) { |
||||
return result; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static XName GetDirectiveName(XamlMember member) |
||||
{ |
||||
XName result; |
||||
if (nameFromDirective.TryGetValue(member, out result)) { |
||||
return result; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public static class ExtensionMethods |
||||
{ |
||||
public static V FindOrCreate<K, V>(this Dictionary<K, V> dict, K key) where V : new() |
||||
{ |
||||
V value; |
||||
if (!dict.TryGetValue(key, out value)) { |
||||
value = new V(); |
||||
dict[key] = value; |
||||
} |
||||
return value; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public interface IHasAnnotations |
||||
{ |
||||
void AnnotateWith<T>(T annotation) where T : class; |
||||
T GetAnnotation<T>() where T : class; |
||||
} |
||||
} |
@ -0,0 +1,238 @@
@@ -0,0 +1,238 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.ComponentModel; |
||||
using System.Windows.Markup; |
||||
using System.Windows; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
class InstanceTracker : Tracker |
||||
{ |
||||
public override void Add(MemberNode memberNode) |
||||
{ |
||||
foreach (var valueNode in memberNode.Values) { |
||||
Add(valueNode); |
||||
} |
||||
} |
||||
|
||||
public override void Add(ObjectNode objectNode) |
||||
{ |
||||
if (objectNode.Instance == null) { |
||||
Instantiate(objectNode); |
||||
} |
||||
var parentMember = objectNode.ParentMember; |
||||
if (parentMember != null) { |
||||
if (parentMember.Member == IntristicMember.Items) { |
||||
var collectionObjectNode = parentMember.ParentObject; |
||||
if (collectionObjectNode.Type.IsDictionary) { |
||||
//var keyValue = objectNode.Key.Value;
|
||||
//if (keyValue != null) {
|
||||
// Runtime.Add(collectionObjectNode.Instance,
|
||||
// keyValue.Instance, objectNode.Instance);
|
||||
//}
|
||||
} |
||||
else { |
||||
Runtime.Add(collectionObjectNode.Instance, objectNode.Instance); |
||||
} |
||||
} |
||||
else { |
||||
if (!objectNode.IsRetrieved) { |
||||
object valueInstance; |
||||
if (objectNode.Type.IsMarkupExtension) { |
||||
valueInstance = ProvideValue(objectNode); |
||||
} |
||||
else { |
||||
valueInstance = objectNode.Instance; |
||||
} |
||||
Runtime.SetValue(parentMember, valueInstance); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override void Add(TextNode textNode) |
||||
{ |
||||
var parentMember = textNode.ParentMember; |
||||
if (parentMember != null) { |
||||
textNode.Instance = Runtime.ConvertFromText( |
||||
parentMember.Property.XamlContext, |
||||
textNode.Text); |
||||
|
||||
if (parentMember.Member == IntristicMember.Items) { |
||||
// IAddChild support.
|
||||
// Instance could differ without it (e.g. TextBlock.Inlines vs TextBlock.Text)
|
||||
var grandParentMember = parentMember.ParentObject.ParentMember; |
||||
if (grandParentMember != null) { |
||||
var addChild = grandParentMember.ParentObject.Instance as IAddChild; |
||||
if (addChild != null) { |
||||
addChild.AddText(textNode.Text); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
Runtime.Add(parentMember.ParentObject.Instance, textNode.Instance); |
||||
} |
||||
else { |
||||
Runtime.SetValue(parentMember, textNode.Instance); |
||||
if (parentMember.Member == Directive.Key) { |
||||
Runtime.Add(parentMember.ParentObject.ParentObject.Instance, |
||||
textNode.Instance, parentMember.ParentObject.Instance); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override void Remove(MemberNode node, ObjectNode parent) |
||||
{ |
||||
Runtime.ResetValue(parent.Instance, node.Member); |
||||
} |
||||
|
||||
public override void Remove(ObjectNode node, MemberNode parent) |
||||
{ |
||||
if (parent != null && parent.Member == IntristicMember.Items) { |
||||
Runtime.Remove(parent.ParentObject.Instance, node.Instance); |
||||
} |
||||
} |
||||
|
||||
void Instantiate(ObjectNode objectNode) |
||||
{ |
||||
var parentMember = objectNode.ParentMember; |
||||
ISupportInitialize supportInitialize = null; |
||||
|
||||
if (objectNode.IsRetrieved) { |
||||
objectNode.Instance = Runtime.GetValue(parentMember); |
||||
} |
||||
else { |
||||
if (objectNode.InitializationText.IsSet) { |
||||
objectNode.Instance = Runtime.ConvertFromText( |
||||
objectNode.InitializationText.XamlContext, |
||||
objectNode.InitializationText.ValueText); |
||||
} |
||||
else { |
||||
var ctorNode = objectNode.FindMemberNode(IntristicMember.ConsructorArgs); |
||||
if (ctorNode != null) { |
||||
objectNode.Instance = Construct(ctorNode); |
||||
} |
||||
else { |
||||
objectNode.Instance = Runtime.CreateInstance(objectNode.Type, null); |
||||
} |
||||
} |
||||
|
||||
supportInitialize = objectNode.Instance as ISupportInitialize; |
||||
if (supportInitialize != null) { |
||||
supportInitialize.BeginInit(); |
||||
} |
||||
} |
||||
|
||||
foreach (var memberNode in objectNode.MemberNodes) { |
||||
if (memberNode.Member == IntristicMember.ConsructorArgs) continue; |
||||
Add(memberNode); |
||||
} |
||||
|
||||
if (supportInitialize != null) { |
||||
supportInitialize.EndInit(); |
||||
} |
||||
} |
||||
|
||||
object Construct(MemberNode ctorNode) |
||||
{ |
||||
var objectNode = ctorNode.ParentObject; |
||||
var args = new List<object>(); |
||||
var ctor = objectNode.Type.Constructors.First( |
||||
c => c.Arguments.Count() == ctorNode.Values.Count); |
||||
|
||||
for (int i = 0; i < ctorNode.Values.Count; i++) { |
||||
var ctorArgValue = ctorNode.Values[i]; |
||||
Add(ctorArgValue); |
||||
|
||||
var value = ctorArgValue.Instance; |
||||
var targetType = ctor.Arguments[i]; |
||||
if (!targetType.SystemType.IsAssignableFrom(value.GetType())) { |
||||
var text = value as string; |
||||
if (text != null) { |
||||
value = Runtime.ConvertFromText(ctorNode.Property.XamlContext, targetType, text); |
||||
} |
||||
else { |
||||
throw new XamlException("Cannot convert"); |
||||
} |
||||
} |
||||
args.Add(value); |
||||
} |
||||
return Runtime.CreateInstance(objectNode.Type, args.ToArray()); |
||||
} |
||||
|
||||
object ProvideValue(ObjectNode node) |
||||
{ |
||||
var me = node.Instance as MarkupExtension; |
||||
|
||||
Instantiate(node); |
||||
|
||||
if (me is StaticResourceExtension) { |
||||
return FindResource(node, (me as StaticResourceExtension).ResourceKey); |
||||
} |
||||
else if (me is DynamicResourceExtension) { |
||||
return FindResource(node, (me as DynamicResourceExtension).ResourceKey); |
||||
} |
||||
|
||||
return me.ProvideValue(node.ParentMember.Property.XamlContext); |
||||
} |
||||
|
||||
object FindResource(ObjectNode node, object key) |
||||
{ |
||||
if (key == null) return null; |
||||
|
||||
var current = node; |
||||
while (current != null) { |
||||
var result = GetResource(current.Instance, key); |
||||
if (result != Runtime.UnsetValue) { |
||||
return result; |
||||
} |
||||
current = current.ParentObject; |
||||
} |
||||
|
||||
var appDefinition = node.Document.Project.ApplicationDefinition; |
||||
if (appDefinition != null) { |
||||
var app = appDefinition.Root.Instance as Application; |
||||
if (app != null) { |
||||
var result = GetResource(app, key); |
||||
if (result != Runtime.UnsetValue) { |
||||
return result; |
||||
} |
||||
} |
||||
} |
||||
//if (key is ComponentResourceKey)
|
||||
//{
|
||||
// fore
|
||||
//}
|
||||
return null; |
||||
} |
||||
|
||||
public static object GetResource(object container, object key) |
||||
{ |
||||
var resources = GetResources(container); |
||||
if (resources != null && resources.Contains(key)) { |
||||
return resources[key]; |
||||
} |
||||
return Runtime.UnsetValue; |
||||
} |
||||
|
||||
public static ResourceDictionary GetResources(object container) |
||||
{ |
||||
if (container is FrameworkElement) { |
||||
return (container as FrameworkElement).Resources; |
||||
} |
||||
if (container is FrameworkTemplate) { |
||||
return (container as FrameworkTemplate).Resources; |
||||
} |
||||
if (container is Style) { |
||||
return (container as Style).Resources; |
||||
} |
||||
if (container is Application) { |
||||
return (container as Application).Resources; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,83 @@
@@ -0,0 +1,83 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Xml.Linq; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class IntristicMember : XamlMember |
||||
{ |
||||
public IntristicMember(string name) |
||||
{ |
||||
this.name = name; |
||||
} |
||||
|
||||
public static XamlMember Items = new IntristicMember("Items"); |
||||
public static XamlMember ConsructorArgs = new IntristicMember("ConsructorArgs"); |
||||
public static XamlMember InitializationText = new IntristicMember("InitializationText"); |
||||
public static XamlMember DirectiveChildren = new IntristicMember("DirectiveChildren"); |
||||
|
||||
string name; |
||||
|
||||
public override string Name |
||||
{ |
||||
get { return name; } |
||||
} |
||||
|
||||
public override XamlType OwnerType |
||||
{ |
||||
get { return null; } |
||||
} |
||||
|
||||
public override XamlType ValueType |
||||
{ |
||||
get { return ReflectionMapper.GetXamlType(typeof(object)); } |
||||
} |
||||
|
||||
public override XamlType TargetType |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override AllowedLocation AllowedLocation |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsEvent |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsDirective |
||||
{ |
||||
get { return true; } |
||||
} |
||||
|
||||
public override bool IsReadOnly |
||||
{ |
||||
get { return false; } |
||||
} |
||||
|
||||
public override bool IsStatic |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsAttachable |
||||
{ |
||||
get { return false; } |
||||
} |
||||
|
||||
public override T GetAttribute<T>() |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public override bool HasTextSyntax |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,151 @@
@@ -0,0 +1,151 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Xml.Linq; |
||||
using System.Windows.Markup; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class IntristicType : XamlType |
||||
{ |
||||
public static XName CodeName = XamlConstants.XamlNamespace + "Code"; |
||||
public static XName XDataName = XamlConstants.XamlNamespace + "XData"; |
||||
|
||||
public static XamlType Code = new IntristicType(); |
||||
public static XamlType XData = new IntristicType(); |
||||
|
||||
public static XamlType String = ReflectionMapper.GetXamlType(typeof(string)); |
||||
public static XamlType MarkupExtension = ReflectionMapper.GetXamlType(typeof(MarkupExtension)); |
||||
|
||||
public override string Name |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsDefaultConstructible |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsNullable |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override IEnumerable<XamlMember> Members |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlMember ContentProperty |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlMember DictionaryKeyProperty |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlMember NameProperty |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlMember XmlLangProperty |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool TrimSurroundingWhitespace |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsWhitespaceSignificantCollection |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsCollection |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsDictionary |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override IEnumerable<XamlType> AllowedTypes |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override IEnumerable<XamlType> AllowedKeyTypes |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsXData |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsNameScope |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override IEnumerable<Constructor> Constructors |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlType ReturnValueType |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override string Namespace |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlAssembly Assembly |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlMember Member(string name) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public override bool IsAssignableFrom(XamlType type) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public override IEnumerable<XamlType> ContentWrappers |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool HasTextSyntax |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override Type SystemType |
||||
{ |
||||
get { return null; } |
||||
} |
||||
|
||||
public override T GetAttribute<T>() |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,209 @@
@@ -0,0 +1,209 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
class MarkupExtensionParser |
||||
{ |
||||
public static MarkupExtensionAst Parse(string text) |
||||
{ |
||||
var tokens = MarkupExtensionTokenizer.Tokenize(text); |
||||
|
||||
if (tokens.Count < 3 || |
||||
tokens[0].Kind != MarkupExtensionTokenKind.OpenBrace || |
||||
tokens[1].Kind != MarkupExtensionTokenKind.TypeName || |
||||
tokens[tokens.Count - 1].Kind != MarkupExtensionTokenKind.CloseBrace) { |
||||
throw new XamlException("Invalid markup extension"); |
||||
} |
||||
|
||||
var result = new MarkupExtensionAst(); |
||||
result.TypeName = tokens[1].Value; |
||||
|
||||
for (int i = 2; i < tokens.Count - 1; i++) { |
||||
if (tokens[i].Kind == MarkupExtensionTokenKind.String) { |
||||
result.PositionalArgs.Add(tokens[i].Value); |
||||
} |
||||
else if (tokens[i].Kind == MarkupExtensionTokenKind.Membername) { |
||||
if (tokens[i + 1].Kind != MarkupExtensionTokenKind.Equals || |
||||
tokens[i + 2].Kind != MarkupExtensionTokenKind.String) { |
||||
throw new XamlException("Invalid markup extension"); |
||||
} |
||||
var namedArg = new KeyValuePair<string, string>(tokens[i].Value, tokens[i + 2].Value); |
||||
result.NamedArgs.Add(namedArg); |
||||
i += 2; |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
} |
||||
|
||||
class MarkupExtensionAst |
||||
{ |
||||
public string TypeName; |
||||
public List<string> PositionalArgs = new List<string>(); |
||||
public List<KeyValuePair<string, string>> NamedArgs = new List<KeyValuePair<string, string>>(); |
||||
} |
||||
|
||||
class MarkupExtensionTokenizer |
||||
{ |
||||
private MarkupExtensionTokenizer() { } |
||||
|
||||
string text; |
||||
int pos; |
||||
List<MarkupExtensionToken> tokens = new List<MarkupExtensionToken>(); |
||||
|
||||
public static List<MarkupExtensionToken> Tokenize(string text) |
||||
{ |
||||
MarkupExtensionTokenizer t = new MarkupExtensionTokenizer(); |
||||
t.text = text; |
||||
t.Parse(); |
||||
return t.tokens; |
||||
} |
||||
|
||||
void AddToken(MarkupExtensionTokenKind kind, string val) |
||||
{ |
||||
tokens.Add(new MarkupExtensionToken(kind, val)); |
||||
} |
||||
|
||||
void Parse() |
||||
{ |
||||
AddToken(MarkupExtensionTokenKind.OpenBrace, "{"); |
||||
Expect('{'); |
||||
ConsumeWhitespace(); |
||||
CheckNotEOF(); |
||||
|
||||
StringBuilder b = new StringBuilder(); |
||||
while (pos < text.Length && !char.IsWhiteSpace(text, pos) && text[pos] != '}') |
||||
b.Append(text[pos++]); |
||||
AddToken(MarkupExtensionTokenKind.TypeName, b.ToString()); |
||||
|
||||
ConsumeWhitespace(); |
||||
while (pos < text.Length) { |
||||
switch (text[pos]) { |
||||
case '}': |
||||
AddToken(MarkupExtensionTokenKind.CloseBrace, "}"); |
||||
pos++; |
||||
break; |
||||
case '=': |
||||
AddToken(MarkupExtensionTokenKind.Equals, "="); |
||||
pos++; |
||||
break; |
||||
case ',': |
||||
AddToken(MarkupExtensionTokenKind.Comma, ","); |
||||
pos++; |
||||
break; |
||||
default: |
||||
MembernameOrString(); |
||||
break; |
||||
} |
||||
ConsumeWhitespace(); |
||||
} |
||||
} |
||||
|
||||
void MembernameOrString() |
||||
{ |
||||
StringBuilder b = new StringBuilder(); |
||||
if (text[pos] == '"' || text[pos] == '\'') { |
||||
char quote = text[pos++]; |
||||
CheckNotEOF(); |
||||
while (!(text[pos] == quote && text[pos - 1] != '\\')) { |
||||
char c = text[pos++]; |
||||
if (c != '\\') |
||||
b.Append(c); |
||||
CheckNotEOF(); |
||||
} |
||||
pos++; // consume closing quote
|
||||
ConsumeWhitespace(); |
||||
} |
||||
else { |
||||
int braceTotal = 0; |
||||
while (true) { |
||||
CheckNotEOF(); |
||||
switch (text[pos]) { |
||||
case '\\': |
||||
pos++; |
||||
CheckNotEOF(); |
||||
b.Append(text[pos++]); |
||||
break; |
||||
case '{': |
||||
b.Append(text[pos++]); |
||||
braceTotal++; |
||||
break; |
||||
case '}': |
||||
if (braceTotal == 0) goto stop; |
||||
b.Append(text[pos++]); |
||||
braceTotal--; |
||||
break; |
||||
case ',': |
||||
case '=': |
||||
if (braceTotal == 0) goto stop; |
||||
b.Append(text[pos++]); |
||||
break; |
||||
default: |
||||
b.Append(text[pos++]); |
||||
break; |
||||
} |
||||
} |
||||
stop: ; |
||||
} |
||||
CheckNotEOF(); |
||||
string valueText = b.ToString(); |
||||
if (text[pos] == '=') { |
||||
AddToken(MarkupExtensionTokenKind.Membername, valueText.Trim()); |
||||
} |
||||
else { |
||||
AddToken(MarkupExtensionTokenKind.String, valueText); |
||||
} |
||||
} |
||||
|
||||
void Expect(char c) |
||||
{ |
||||
CheckNotEOF(); |
||||
if (text[pos] != c) |
||||
throw new XamlException("Expected '" + c + "'"); |
||||
pos++; |
||||
} |
||||
|
||||
void ConsumeWhitespace() |
||||
{ |
||||
while (pos < text.Length && char.IsWhiteSpace(text, pos)) |
||||
pos++; |
||||
} |
||||
|
||||
void CheckNotEOF() |
||||
{ |
||||
if (pos >= text.Length) |
||||
throw new XamlException("Unexpected end of markup extension"); |
||||
} |
||||
} |
||||
|
||||
class MarkupExtensionToken |
||||
{ |
||||
public MarkupExtensionToken(MarkupExtensionTokenKind kind, string value) |
||||
{ |
||||
this.Kind = kind; |
||||
this.Value = value; |
||||
} |
||||
|
||||
public readonly MarkupExtensionTokenKind Kind; |
||||
public readonly string Value; |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[" + Kind + " " + Value + "]"; |
||||
} |
||||
} |
||||
|
||||
enum MarkupExtensionTokenKind |
||||
{ |
||||
OpenBrace, |
||||
CloseBrace, |
||||
Equals, |
||||
Comma, |
||||
TypeName, |
||||
Membername, |
||||
String |
||||
} |
||||
} |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Xaml |
||||
{ |
||||
public static class MarkupExtensionPrinter |
||||
{ |
||||
public static bool CanPrint(XamlObject obj) |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
public static string Print(XamlObject obj) |
||||
{ |
||||
StringBuilder sb = new StringBuilder(); |
||||
sb.Append("{"); |
||||
sb.Append(obj.GetNameForMarkupExtension()); |
||||
|
||||
bool first = true; |
||||
foreach (var property in obj.Properties) { |
||||
if (!property.IsSet) continue; |
||||
|
||||
if (first) |
||||
sb.Append(" "); |
||||
else |
||||
sb.Append(", "); |
||||
first = false; |
||||
|
||||
sb.Append(property.GetNameForMarkupExtension()); |
||||
sb.Append("="); |
||||
|
||||
var value = property.PropertyValue; |
||||
if (value is XamlTextValue) { |
||||
sb.Append((value as XamlTextValue).Text); |
||||
} else if (value is XamlObject) { |
||||
sb.Append(Print(value as XamlObject)); |
||||
} |
||||
} |
||||
sb.Append("}"); |
||||
return sb.ToString(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,71 @@
@@ -0,0 +1,71 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Diagnostics; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class MemberNode : XamlNode |
||||
{ |
||||
internal MemberNode() |
||||
{ |
||||
Values = new NodeCollection<XamlValue>(this); |
||||
} |
||||
|
||||
public XamlMember Member; |
||||
public NodeCollection<XamlValue> Values; |
||||
|
||||
public ObjectNode ParentObject |
||||
{ |
||||
get { return ParentNode as ObjectNode; } |
||||
} |
||||
|
||||
public XamlProperty Property |
||||
{ |
||||
get |
||||
{ |
||||
if (ParentObject != null) { |
||||
return ParentObject.Property(Member); |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public XamlValue SingleValue |
||||
{ |
||||
get |
||||
{ |
||||
if (Values.Count == 1) { |
||||
return Values[0]; |
||||
} |
||||
return null; |
||||
} |
||||
set |
||||
{ |
||||
if (Values.Count == 1) { |
||||
Values[0] = value; |
||||
} |
||||
else { |
||||
Values.Clear(); |
||||
Values.Add(value); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return GetType().Name + ": " + Member.Name; |
||||
} |
||||
|
||||
public override IEnumerable<XamlNode> Nodes() |
||||
{ |
||||
return Values.Cast<XamlNode>(); |
||||
} |
||||
|
||||
protected override void RemoveChild(XamlNode node) |
||||
{ |
||||
Values.Remove(node as XamlValue); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Collections.ObjectModel; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class NodeCollection<T> : Collection<T> where T : XamlNode |
||||
{ |
||||
public NodeCollection(XamlNode parent) |
||||
{ |
||||
this.parent = parent; |
||||
} |
||||
|
||||
XamlNode parent; |
||||
|
||||
protected override void InsertItem(int index, T item) |
||||
{ |
||||
base.InsertItem(index, item); |
||||
item.ParentNode = parent; |
||||
if (item.Document != null) { |
||||
var e = new DocumentChangedEventArgs() { NewNode = item }; |
||||
item.Document.RaiseDocumentChanged(e); |
||||
} |
||||
} |
||||
|
||||
protected override void RemoveItem(int index) |
||||
{ |
||||
var item = this[index]; |
||||
base.RemoveItem(index); |
||||
if (item.Document != null) { |
||||
var e = new DocumentChangedEventArgs() { OldNode = item, OldParent = item.ParentNode }; |
||||
item.ParentNode = null; |
||||
item.Document.RaiseDocumentChanged(e); |
||||
} |
||||
else { |
||||
item.ParentNode = null; |
||||
} |
||||
} |
||||
|
||||
protected override void SetItem(int index, T item) |
||||
{ |
||||
var oldItem = this[index]; |
||||
base.SetItem(index, item); |
||||
if (item.Document != null) { |
||||
var e = new DocumentChangedEventArgs() { |
||||
OldNode = oldItem, |
||||
OldParent = oldItem.ParentNode, |
||||
NewNode = item |
||||
}; |
||||
oldItem.ParentNode = null; |
||||
item.ParentNode = parent; |
||||
item.Document.RaiseDocumentChanged(e); |
||||
} |
||||
else { |
||||
oldItem.ParentNode = null; |
||||
} |
||||
} |
||||
|
||||
protected override void ClearItems() |
||||
{ |
||||
while (Count > 0) { |
||||
RemoveItem(Count - 1); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,154 @@
@@ -0,0 +1,154 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Diagnostics; |
||||
using System.Collections.ObjectModel; |
||||
using System.Windows; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class ObjectNode : XamlValue |
||||
{ |
||||
internal ObjectNode() |
||||
{ |
||||
MemberNodes = new NodeCollection<MemberNode>(this); |
||||
} |
||||
|
||||
internal ObjectNode(XamlDocument doc, object instance) |
||||
: this() |
||||
{ |
||||
Document = doc; |
||||
Instance = instance; |
||||
Type = ReflectionMapper.GetXamlType(instance.GetType()); |
||||
} |
||||
|
||||
public XamlType Type; |
||||
public bool IsRetrieved; |
||||
public NodeCollection<MemberNode> MemberNodes; |
||||
Dictionary<XamlMember, XamlProperty> properties = new Dictionary<XamlMember, XamlProperty>(); |
||||
|
||||
public bool IsDocumentRoot |
||||
{ |
||||
get { return Document.Root == this; } |
||||
} |
||||
|
||||
public XamlProperty Content |
||||
{ |
||||
get |
||||
{ |
||||
if (Type.ContentProperty != null) { |
||||
return Property(Type.ContentProperty); |
||||
} |
||||
if (Type.IsCollection) { |
||||
return Property(IntristicMember.Items); |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public XamlProperty InitializationText |
||||
{ |
||||
get { return Property(IntristicMember.InitializationText); } |
||||
} |
||||
|
||||
public string Name |
||||
{ |
||||
get |
||||
{ |
||||
var nameProperty = Property(Type.NameProperty); |
||||
if (nameProperty != null && nameProperty.IsSet) { |
||||
return nameProperty.ValueText; |
||||
} |
||||
var xNameProperty = Property(Directive.Name); |
||||
return xNameProperty.ValueText; |
||||
} |
||||
set |
||||
{ |
||||
var nameProperty = Property(Type.NameProperty); |
||||
var xNameProperty = Property(Directive.Name); |
||||
|
||||
if (nameProperty != null) { |
||||
nameProperty.Reset(); |
||||
} |
||||
|
||||
xNameProperty.Set(value); |
||||
} |
||||
} |
||||
|
||||
public XamlProperty Key |
||||
{ |
||||
get { return Property(Directive.Key); } |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return GetType().Name + ": " + Type.Name; |
||||
} |
||||
|
||||
public override IEnumerable<XamlNode> Nodes() |
||||
{ |
||||
return MemberNodes.Cast<XamlNode>(); |
||||
} |
||||
|
||||
protected override void RemoveChild(XamlNode node) |
||||
{ |
||||
MemberNodes.Remove(node as MemberNode); |
||||
} |
||||
|
||||
public MemberNode FindMemberNode(XamlMember member) |
||||
{ |
||||
foreach (var memberNode in MemberNodes) { |
||||
if (memberNode.Member == member) { |
||||
return memberNode; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public MemberNode EnsureMemberNode(XamlMember member) |
||||
{ |
||||
var memberNode = FindMemberNode(member); |
||||
if (memberNode == null) { |
||||
memberNode = new MemberNode() { Document = Document, Member = member }; |
||||
MemberNodes.Add(memberNode); |
||||
|
||||
if (member.IsReadOnly) { |
||||
var collection = new ObjectNode() { |
||||
Document = Document, |
||||
Type = member.ValueType, |
||||
IsRetrieved = true |
||||
}; |
||||
memberNode.SingleValue = collection; |
||||
} |
||||
} |
||||
return memberNode; |
||||
} |
||||
|
||||
public XamlProperty Property(string name) |
||||
{ |
||||
return Property(Type.Member(name)); |
||||
} |
||||
|
||||
public XamlProperty Property(DependencyProperty dp) |
||||
{ |
||||
return Property(dp.Name) ?? Property(dp.OwnerType, dp.Name); |
||||
} |
||||
|
||||
public XamlProperty Property(Type type, string name) |
||||
{ |
||||
return Property(ReflectionMapper.GetXamlType(type).Member(name)); |
||||
} |
||||
|
||||
public XamlProperty Property(XamlMember member) |
||||
{ |
||||
if (member == null) return null; |
||||
XamlProperty property; |
||||
if (!properties.TryGetValue(member, out property)) { |
||||
property = new XamlProperty(this, member); |
||||
properties[member] = property; |
||||
} |
||||
return property; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Reflection; |
||||
using System.Windows.Markup; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class ReflectionAssembly : XamlAssembly |
||||
{ |
||||
internal ReflectionAssembly(Assembly assembly) |
||||
{ |
||||
Assembly = assembly; |
||||
} |
||||
|
||||
public Assembly Assembly; |
||||
|
||||
public override string Name |
||||
{ |
||||
get { return Assembly.GetName().Name; } |
||||
} |
||||
|
||||
public override IEnumerable<XmlnsDefinitionAttribute> XmlnsDefinitions |
||||
{ |
||||
get { return Assembly.GetCustomAttributes(typeof(XmlnsDefinitionAttribute), false) as XmlnsDefinitionAttribute[]; } |
||||
} |
||||
|
||||
public override XamlType GetType(string fullName) |
||||
{ |
||||
var type = Assembly.GetType(fullName); |
||||
if (type != null) { |
||||
return ReflectionMapper.GetXamlType(type); |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Reflection; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public static class ReflectionMapper |
||||
{ |
||||
static Dictionary<object, XamlAssembly> assemblies = new Dictionary<object, XamlAssembly>(); |
||||
static Dictionary<object, XamlType> types = new Dictionary<object, XamlType>(); |
||||
static Dictionary<object, XamlMember> members = new Dictionary<object, XamlMember>(); |
||||
|
||||
public static XamlAssembly GetXamlAssembly(Assembly key) |
||||
{ |
||||
XamlAssembly result; |
||||
if (!assemblies.TryGetValue(key, out result)) { |
||||
result = new ReflectionAssembly(key); |
||||
assemblies[key] = result; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
public static XamlType GetXamlType(Type key) |
||||
{ |
||||
XamlType result; |
||||
if (!types.TryGetValue(key, out result)) { |
||||
result = new ReflectionType(key); |
||||
types[key] = result; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
public static XamlMember GetXamlMember(ReflectionMemberInfo key) |
||||
{ |
||||
XamlMember result; |
||||
if (!members.TryGetValue(key, out result)) { |
||||
result = new ReflectionMember(key); |
||||
members[key] = result; |
||||
} |
||||
return result; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,87 @@
@@ -0,0 +1,87 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Reflection; |
||||
using System.Diagnostics; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class ReflectionMember : XamlMember |
||||
{ |
||||
internal ReflectionMember(ReflectionMemberInfo info) |
||||
{ |
||||
this.info = info; |
||||
} |
||||
|
||||
ReflectionMemberInfo info; |
||||
|
||||
public ReflectionMemberInfo Info |
||||
{ |
||||
get { return info; } |
||||
} |
||||
|
||||
public override string Name |
||||
{ |
||||
get { return info.Name; } |
||||
} |
||||
|
||||
public override XamlType OwnerType |
||||
{ |
||||
get { return ReflectionMapper.GetXamlType(info.OwnerType); } |
||||
} |
||||
|
||||
public override XamlType ValueType |
||||
{ |
||||
get |
||||
{ |
||||
return ReflectionMapper.GetXamlType(info.ValueType); |
||||
} |
||||
} |
||||
|
||||
public override XamlType TargetType |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override AllowedLocation AllowedLocation |
||||
{ |
||||
get { return AllowedLocation.Any; } |
||||
} |
||||
|
||||
public override bool IsEvent |
||||
{ |
||||
get { return Info is ReflectionEventInfo; } |
||||
} |
||||
|
||||
public override bool IsDirective |
||||
{ |
||||
get { return false; } |
||||
} |
||||
|
||||
public override bool IsReadOnly |
||||
{ |
||||
get { return Info.IsReadOnly; } |
||||
} |
||||
|
||||
public override bool IsStatic |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsAttachable |
||||
{ |
||||
get { return Info is ReflectionAttachedPropertyInfo || Info is DependencyPropertyInfo; } |
||||
} |
||||
|
||||
public override T GetAttribute<T>() |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public override bool HasTextSyntax |
||||
{ |
||||
get { return Runtime.GetValueSerializer(this) != null; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,284 @@
@@ -0,0 +1,284 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Reflection; |
||||
using System.ComponentModel; |
||||
using System.Windows; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public abstract class ReflectionMemberInfo |
||||
{ |
||||
public abstract string Name { get; } |
||||
public abstract Type ValueType { get; } |
||||
public abstract Type OwnerType { get; } |
||||
public abstract object GetValue(object instance); |
||||
public abstract void SetValue(object instance, object value); |
||||
public abstract void ResetValue(object instance); |
||||
public abstract bool IsReadOnly { get; } |
||||
public abstract PropertyDescriptor PropertyDescriptor { get; } |
||||
protected abstract object EqualiltyCore { get; } |
||||
|
||||
public DependencyProperty DependencyProperty |
||||
{ |
||||
get |
||||
{ |
||||
var dpd = DependencyPropertyDescriptor.FromProperty(PropertyDescriptor); |
||||
if (dpd != null) { |
||||
return dpd.DependencyProperty; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
var other = obj as ReflectionMemberInfo; |
||||
if (other != null) { |
||||
return EqualiltyCore == other.EqualiltyCore; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return EqualiltyCore.GetHashCode(); |
||||
} |
||||
} |
||||
|
||||
class ReflectionPropertyInfo : ReflectionMemberInfo |
||||
{ |
||||
public ReflectionPropertyInfo(PropertyDescriptor pd) |
||||
{ |
||||
this.pd = pd; |
||||
} |
||||
|
||||
PropertyDescriptor pd; |
||||
|
||||
public override string Name |
||||
{ |
||||
get { return pd.Name; } |
||||
} |
||||
|
||||
public override Type ValueType |
||||
{ |
||||
get { return pd.PropertyType; } |
||||
} |
||||
|
||||
public override Type OwnerType |
||||
{ |
||||
get { return pd.ComponentType; } |
||||
} |
||||
|
||||
public override object GetValue(object instance) |
||||
{ |
||||
return pd.GetValue(instance); |
||||
} |
||||
|
||||
public override void SetValue(object instance, object value) |
||||
{ |
||||
pd.SetValue(instance, value); |
||||
} |
||||
|
||||
public override void ResetValue(object instance) |
||||
{ |
||||
if (pd.CanResetValue(instance)) { |
||||
pd.ResetValue(instance); |
||||
} |
||||
else { |
||||
pd.SetValue(instance, null); |
||||
} |
||||
} |
||||
|
||||
protected override object EqualiltyCore |
||||
{ |
||||
get { return pd; } |
||||
} |
||||
|
||||
public override bool IsReadOnly |
||||
{ |
||||
get { return pd.IsReadOnly; } |
||||
} |
||||
|
||||
public override PropertyDescriptor PropertyDescriptor |
||||
{ |
||||
get { return pd; } |
||||
} |
||||
} |
||||
|
||||
class ReflectionAttachedPropertyInfo : ReflectionMemberInfo |
||||
{ |
||||
public ReflectionAttachedPropertyInfo(MethodInfo getter, MethodInfo setter) |
||||
{ |
||||
this.getter = getter; |
||||
this.setter = setter; |
||||
} |
||||
|
||||
MethodInfo getter; |
||||
MethodInfo setter; |
||||
|
||||
public override string Name |
||||
{ |
||||
get { return setter.Name.Substring(3); } |
||||
} |
||||
|
||||
public override Type ValueType |
||||
{ |
||||
get { return setter.GetParameters()[1].ParameterType; } |
||||
} |
||||
|
||||
public override Type OwnerType |
||||
{ |
||||
get { return setter.DeclaringType; } |
||||
} |
||||
|
||||
public override object GetValue(object instance) |
||||
{ |
||||
if (getter != null) { |
||||
return getter.Invoke(instance, null); |
||||
} |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public override void SetValue(object instance, object value) |
||||
{ |
||||
setter.Invoke(instance, new[] { instance, value }); |
||||
} |
||||
|
||||
public override void ResetValue(object instance) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
protected override object EqualiltyCore |
||||
{ |
||||
get { return setter; } |
||||
} |
||||
|
||||
public override bool IsReadOnly |
||||
{ |
||||
get { return false; } |
||||
} |
||||
|
||||
public override PropertyDescriptor PropertyDescriptor |
||||
{ |
||||
get { return null; } |
||||
} |
||||
} |
||||
|
||||
class DependencyPropertyInfo : ReflectionMemberInfo |
||||
{ |
||||
public DependencyPropertyInfo(DependencyProperty dp) |
||||
{ |
||||
this.dp = dp; |
||||
if (typeof(DependencyObject).IsAssignableFrom(dp.OwnerType)) { |
||||
this.dpd = DependencyPropertyDescriptor.FromProperty(dp, dp.OwnerType); |
||||
} |
||||
} |
||||
|
||||
DependencyProperty dp; |
||||
DependencyPropertyDescriptor dpd; |
||||
|
||||
public override string Name |
||||
{ |
||||
get { return dp.Name; } |
||||
} |
||||
|
||||
public override Type ValueType |
||||
{ |
||||
get { return dp.PropertyType; } |
||||
} |
||||
|
||||
public override Type OwnerType |
||||
{ |
||||
get { return dp.OwnerType; } |
||||
} |
||||
|
||||
public override object GetValue(object instance) |
||||
{ |
||||
var d = instance as DependencyObject; |
||||
return d.GetValue(dp); |
||||
} |
||||
|
||||
public override void SetValue(object instance, object value) |
||||
{ |
||||
var d = instance as DependencyObject; |
||||
d.SetValue(dp, value); |
||||
} |
||||
|
||||
public override void ResetValue(object instance) |
||||
{ |
||||
var d = instance as DependencyObject; |
||||
d.ClearValue(dp); |
||||
} |
||||
|
||||
protected override object EqualiltyCore |
||||
{ |
||||
get { return dp; } |
||||
} |
||||
|
||||
public override bool IsReadOnly |
||||
{ |
||||
get { return dp.ReadOnly; } |
||||
} |
||||
|
||||
public override PropertyDescriptor PropertyDescriptor |
||||
{ |
||||
get { return dpd; } |
||||
} |
||||
} |
||||
|
||||
class ReflectionEventInfo : ReflectionMemberInfo |
||||
{ |
||||
public ReflectionEventInfo(EventInfo eventInfo) |
||||
{ |
||||
this.eventInfo = eventInfo; |
||||
} |
||||
|
||||
EventInfo eventInfo; |
||||
|
||||
public override string Name |
||||
{ |
||||
get { return eventInfo.Name; } |
||||
} |
||||
|
||||
public override Type ValueType |
||||
{ |
||||
get { return eventInfo.EventHandlerType; } |
||||
} |
||||
|
||||
public override Type OwnerType |
||||
{ |
||||
get { return eventInfo.DeclaringType; } |
||||
} |
||||
|
||||
public override object GetValue(object instance) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public override void SetValue(object instance, object value) |
||||
{ |
||||
} |
||||
|
||||
public override void ResetValue(object instance) |
||||
{ |
||||
} |
||||
|
||||
protected override object EqualiltyCore |
||||
{ |
||||
get { return eventInfo; } |
||||
} |
||||
|
||||
public override bool IsReadOnly |
||||
{ |
||||
get { return false; } |
||||
} |
||||
|
||||
public override PropertyDescriptor PropertyDescriptor |
||||
{ |
||||
get { return null; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,265 @@
@@ -0,0 +1,265 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Windows.Markup; |
||||
using System.Reflection; |
||||
using System.Collections; |
||||
using System.ComponentModel; |
||||
using System.Windows; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class ReflectionType : XamlType |
||||
{ |
||||
internal ReflectionType(Type type) |
||||
{ |
||||
this.type = type; |
||||
this.propertyDescriptors = TypeDescriptor.GetProperties(type); |
||||
} |
||||
|
||||
Type type; |
||||
PropertyDescriptorCollection propertyDescriptors; |
||||
|
||||
public Type Type |
||||
{ |
||||
get { return type; } |
||||
} |
||||
|
||||
public override string Name |
||||
{ |
||||
get { return type.Name; } |
||||
} |
||||
|
||||
public override bool IsDefaultConstructible |
||||
{ |
||||
get { return type.GetConstructor(Type.EmptyTypes) != null; } |
||||
} |
||||
|
||||
public override bool IsNullable |
||||
{ |
||||
get { return !type.IsValueType; } |
||||
} |
||||
|
||||
public override IEnumerable<XamlMember> Members |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlMember ContentProperty |
||||
{ |
||||
get |
||||
{ |
||||
foreach (ContentPropertyAttribute a in type.GetCustomAttributes(typeof(ContentPropertyAttribute), true)) { |
||||
return Member(a.Name); |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public override XamlMember DictionaryKeyProperty |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override XamlMember NameProperty |
||||
{ |
||||
get |
||||
{ |
||||
foreach (RuntimeNamePropertyAttribute a in type.GetCustomAttributes(typeof(RuntimeNamePropertyAttribute), true)) { |
||||
return Member(a.Name); |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public override XamlMember XmlLangProperty |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool TrimSurroundingWhitespace |
||||
{ |
||||
get |
||||
{ |
||||
foreach (var a in type.GetCustomAttributes(typeof(TrimSurroundingWhitespaceAttribute), true)) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public override bool IsWhitespaceSignificantCollection |
||||
{ |
||||
get |
||||
{ |
||||
foreach (var a in type.GetCustomAttributes(typeof(WhitespaceSignificantCollectionAttribute), true)) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public override bool IsCollection |
||||
{ |
||||
get { return typeof(ICollection).IsAssignableFrom(type); } |
||||
} |
||||
|
||||
public override bool IsDictionary |
||||
{ |
||||
get { return typeof(IDictionary).IsAssignableFrom(type); } |
||||
} |
||||
|
||||
public override IEnumerable<XamlType> AllowedTypes |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override IEnumerable<XamlType> AllowedKeyTypes |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsXData |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override bool IsNameScope |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override IEnumerable<Constructor> Constructors |
||||
{ |
||||
get |
||||
{ |
||||
Dictionary<int, Constructor> ctors = new Dictionary<int, Constructor>(); |
||||
foreach (var ctorInfo in type.GetConstructors()) { |
||||
var parameters = ctorInfo.GetParameters(); |
||||
if (parameters.Length > 0 && !ctors.ContainsKey(parameters.Length)) { |
||||
var ctor = new Constructor(); |
||||
ctor.Arguments = parameters |
||||
.Select(p => ReflectionMapper.GetXamlType(p.ParameterType)).ToArray(); |
||||
|
||||
List<XamlMember> members = new List<XamlMember>(); |
||||
foreach (var p in parameters) { |
||||
var member = MemberCaseInsensetive(p.Name); |
||||
if (member == null) { |
||||
members = null; |
||||
break; |
||||
} |
||||
members.Add(member); |
||||
} |
||||
if (members != null) { |
||||
ctor.CorrespondingMembers = members.ToArray(); |
||||
} |
||||
|
||||
ctors[parameters.Length] = ctor; |
||||
} |
||||
} |
||||
return ctors.Values; |
||||
} |
||||
} |
||||
|
||||
public override XamlType ReturnValueType |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public override string Namespace |
||||
{ |
||||
get { return type.Namespace; } |
||||
} |
||||
|
||||
public override XamlAssembly Assembly |
||||
{ |
||||
get { return ReflectionMapper.GetXamlAssembly(type.Assembly); } |
||||
} |
||||
|
||||
public override XamlMember Member(string name) |
||||
{ |
||||
ReflectionMemberInfo info = null; |
||||
|
||||
var pd = propertyDescriptors[name]; |
||||
if (pd != null) { |
||||
info = new ReflectionPropertyInfo(pd); |
||||
} |
||||
else { |
||||
var eventInfo = type.GetEvent(name, BindingFlags.Public | BindingFlags.Instance); |
||||
if (eventInfo != null) { |
||||
info = new ReflectionEventInfo(eventInfo); |
||||
} |
||||
else { |
||||
// attached dp better than getter/setter cause we have DependencyObject.ClearValue(dp)
|
||||
var field = type.GetField(name + "Property", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); |
||||
if (field != null) { |
||||
var dp = (DependencyProperty)field.GetValue(null); |
||||
if (dp != null) { |
||||
info = new DependencyPropertyInfo(dp); |
||||
} |
||||
} |
||||
if (info == null) { |
||||
var getter = type.GetMethod("Get" + name, BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); |
||||
var setter = type.GetMethod("Set" + name, BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); |
||||
if (setter != null) { |
||||
info = new ReflectionAttachedPropertyInfo(getter, setter); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
if (info != null) { |
||||
return ReflectionMapper.GetXamlMember(info); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
XamlMember MemberCaseInsensetive(string name) |
||||
{ |
||||
foreach (PropertyDescriptor pd in propertyDescriptors) { |
||||
if (pd.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) { |
||||
return ReflectionMapper.GetXamlMember(new ReflectionPropertyInfo(pd)); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public override IEnumerable<XamlType> ContentWrappers |
||||
{ |
||||
get |
||||
{ |
||||
foreach (ContentWrapperAttribute a in type.GetCustomAttributes(typeof(ContentWrapperAttribute), true)) { |
||||
yield return ReflectionMapper.GetXamlType(a.ContentWrapper); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override bool IsAssignableFrom(XamlType other) |
||||
{ |
||||
var r = other as ReflectionType; |
||||
if (r != null) { |
||||
return type.IsAssignableFrom(r.Type); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public override bool HasTextSyntax |
||||
{ |
||||
get { return Runtime.GetValueSerializer(this) != null; } |
||||
} |
||||
|
||||
public override Type SystemType |
||||
{ |
||||
get { return type; } |
||||
} |
||||
|
||||
public override T GetAttribute<T>() |
||||
{ |
||||
var usageAttribute = (AttributeUsageAttribute)typeof(T).GetCustomAttributes(typeof(AttributeUsageAttribute), true)[0]; |
||||
foreach (T attr in type.GetCustomAttributes(typeof(T), usageAttribute.Inherited)) { |
||||
return attr; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,236 @@
@@ -0,0 +1,236 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Collections; |
||||
using System.ComponentModel; |
||||
using System.Windows.Markup; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public static class Runtime |
||||
{ |
||||
public static object UnsetValue = new object(); |
||||
|
||||
static Dictionary<Type, Type> typeReplacers = new Dictionary<Type, Type>(); |
||||
|
||||
public static void AddTypeReplacer(Type type, Type replacer) |
||||
{ |
||||
lock (typeReplacers) { |
||||
typeReplacers[type] = replacer; |
||||
} |
||||
} |
||||
|
||||
public static Type GetTypeReplacer(Type type) |
||||
{ |
||||
Type replacer; |
||||
lock (typeReplacers) { |
||||
typeReplacers.TryGetValue(type, out replacer); |
||||
return replacer; |
||||
} |
||||
} |
||||
|
||||
public static object CreateInstance(XamlType type, object[] args) |
||||
{ |
||||
if (type.SystemType != null) { |
||||
var finalType = GetTypeReplacer(type.SystemType) ?? type.SystemType; |
||||
return Activator.CreateInstance(finalType, args); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static object GetValue(MemberNode memberNode) |
||||
{ |
||||
return GetValue(memberNode.ParentObject.Instance, memberNode.Member); |
||||
} |
||||
|
||||
public static void SetValue(MemberNode memberNode, object value) |
||||
{ |
||||
SetValue(memberNode.ParentObject.Instance, memberNode.Member, value); |
||||
} |
||||
|
||||
public static void ResetValue(MemberNode memberNode) |
||||
{ |
||||
ResetValue(memberNode.ParentObject.Instance, memberNode.Member); |
||||
} |
||||
|
||||
public static object GetValue(object instance, XamlMember member) |
||||
{ |
||||
var info = GetFinalMemberInfo(instance, member); |
||||
if (info != null) { |
||||
return info.GetValue(instance); |
||||
} |
||||
return Runtime.UnsetValue; |
||||
} |
||||
|
||||
public static void SetValue(object instance, XamlMember member, object value) |
||||
{ |
||||
var info = GetFinalMemberInfo(instance, member); |
||||
if (info != null) { |
||||
info.SetValue(instance, value); |
||||
} |
||||
} |
||||
|
||||
public static void ResetValue(object instance, XamlMember member) |
||||
{ |
||||
var info = GetFinalMemberInfo(instance, member); |
||||
if (info != null) { |
||||
info.ResetValue(instance); |
||||
} |
||||
} |
||||
|
||||
static ReflectionMemberInfo GetFinalMemberInfo(object instance, XamlMember member) |
||||
{ |
||||
var result = member as ReflectionMember; |
||||
if (result != null) { |
||||
if (!result.IsAttachable) { |
||||
var designTimeType = instance.GetType(); |
||||
var ownerType = member.OwnerType.SystemType; |
||||
|
||||
if (!ownerType.IsAssignableFrom(designTimeType)) { |
||||
result = ReflectionMapper.GetXamlType(designTimeType) |
||||
.Member(member.Name) as ReflectionMember; |
||||
} |
||||
} |
||||
return result.Info; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static void Add(object collection, object item) |
||||
{ |
||||
IList list = collection as IList; |
||||
list.Add(item); |
||||
} |
||||
|
||||
public static void Add(object collection, object key, object item) |
||||
{ |
||||
IDictionary dict = collection as IDictionary; |
||||
dict.Add(key, item); |
||||
} |
||||
|
||||
public static void Insert(object collection, int index, object item) |
||||
{ |
||||
IList list = collection as IList; |
||||
list.Insert(index, item); |
||||
} |
||||
|
||||
public static void Remove(object collection, object item) |
||||
{ |
||||
IList list = collection as IList; |
||||
if (list != null) { |
||||
list.Remove(item); |
||||
} |
||||
else { |
||||
IDictionary dict = collection as IDictionary; |
||||
object key = null; |
||||
foreach (DictionaryEntry pair in dict) { |
||||
if (pair.Value == item) { |
||||
key = pair.Key; |
||||
break; |
||||
} |
||||
} |
||||
dict.Remove(key); |
||||
} |
||||
} |
||||
|
||||
public static bool TryConvertToText(XamlContext context, object value, out string text) |
||||
{ |
||||
text = null; |
||||
if (value != null) { |
||||
text = ConvertToText(context, value); |
||||
} |
||||
return text != null; |
||||
} |
||||
|
||||
public static string ConvertToText(XamlContext context, object value) |
||||
{ |
||||
var text = StandardValues.GetStandardValueText(value); |
||||
if (text != null) { |
||||
return text; |
||||
} |
||||
var targetType = context.XamlProperty.ValueType.SystemType; |
||||
if (targetType != null) { |
||||
TryConvert(ref value, targetType); |
||||
} |
||||
var valueSerializer = GetValueSerializer(context); |
||||
if (valueSerializer != null && valueSerializer.CanConvertToString(value, context)) { |
||||
return valueSerializer.ConvertToString(value, context); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
static void TryConvert(ref object value, Type targetType) |
||||
{ |
||||
if (!targetType.IsAssignableFrom(value.GetType())) { |
||||
if (value is IConvertible && typeof(IConvertible).IsAssignableFrom(targetType)) { |
||||
value = Convert.ChangeType(value, targetType); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static object ConvertFromText(XamlContext context, string text) |
||||
{ |
||||
var valueSerializer = GetValueSerializer(context); |
||||
if (valueSerializer != null && valueSerializer.CanConvertFromString(text, context)) { |
||||
return valueSerializer.ConvertFromString(text, context); |
||||
} |
||||
return text; |
||||
} |
||||
|
||||
public static object ConvertFromText(XamlContext context, XamlType targetType, string text) |
||||
{ |
||||
var valueSerializer = GetValueSerializer(targetType); |
||||
if (valueSerializer != null && valueSerializer.CanConvertFromString(text, context)) { |
||||
return valueSerializer.ConvertFromString(text, context); |
||||
} |
||||
return text; |
||||
} |
||||
|
||||
public static ValueSerializer GetValueSerializer(XamlContext context) |
||||
{ |
||||
var valueSerializer = GetValueSerializer(context.XamlProperty.Member); |
||||
if (valueSerializer == null) { |
||||
valueSerializer = GetValueSerializer(context.XamlProperty.ValueType); |
||||
} |
||||
return valueSerializer; |
||||
} |
||||
|
||||
public static ValueSerializer GetValueSerializer(XamlType type) |
||||
{ |
||||
if (type.SystemType != null) { |
||||
return ValueSerializer.GetSerializerFor(type.SystemType); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static ValueSerializer GetValueSerializer(XamlMember member) |
||||
{ |
||||
var reflectionMember = member as ReflectionMember; |
||||
if (reflectionMember != null && reflectionMember.Info.PropertyDescriptor != null) { |
||||
return ValueSerializer.GetSerializerFor(reflectionMember.Info.PropertyDescriptor); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static XamlType GetWrapperTypeForInitializationText(object value) |
||||
{ |
||||
var type = value.GetType(); |
||||
Type prev = null; |
||||
|
||||
while (true) { |
||||
if (type == null || ValueSerializer.GetSerializerFor(type) == null) { |
||||
break; |
||||
} |
||||
prev = type; |
||||
type = type.BaseType; |
||||
} |
||||
|
||||
if (prev != null) { |
||||
return ReflectionMapper.GetXamlType(prev); |
||||
} |
||||
|
||||
throw new XamlException("ValueSerializer not found"); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,135 @@
@@ -0,0 +1,135 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Collections; |
||||
using System.Reflection; |
||||
using System.Windows.Input; |
||||
using System.Windows.Media; |
||||
using System.Windows; |
||||
using System.Windows.Documents; |
||||
using System.ComponentModel; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public static class StandardValues |
||||
{ |
||||
static Dictionary<Type, List<StandardValue>> standardValues = new Dictionary<Type, List<StandardValue>>(); |
||||
static Dictionary<object, StandardValue> standardValueFromInstance = new Dictionary<object, StandardValue>(); |
||||
|
||||
public static void AddStandardValues(Type type, Type valuesContainer) |
||||
{ |
||||
AddStandardValues(type, valuesContainer |
||||
.GetProperties(BindingFlags.Public | BindingFlags.Static) |
||||
.Select(p => new StandardValue() { |
||||
Instance = p.GetValue(null, null), |
||||
Text = p.Name |
||||
})); |
||||
} |
||||
|
||||
public static void AddStandardValue(Type type, string text, object value) |
||||
{ |
||||
AddStandardValues(type, new[] { new StandardValue() { Text = text, Instance = value } }); |
||||
} |
||||
|
||||
public static void AddStandardValues(Type type, IEnumerable<StandardValue> values) |
||||
{ |
||||
List<StandardValue> list; |
||||
lock (standardValues) { |
||||
lock (standardValueFromInstance) { |
||||
if (!standardValues.TryGetValue(type, out list)) { |
||||
list = new List<StandardValue>(); |
||||
standardValues[type] = list; |
||||
} |
||||
foreach (var v in values) { |
||||
list.Add(v); |
||||
standardValueFromInstance[v.Instance] = v; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static IEnumerable<StandardValue> GetStandardValues(Type type) |
||||
{ |
||||
if (type.IsEnum) { |
||||
var enumValues = Enum.GetValues(type); |
||||
var enumNames = Enum.GetNames(type); |
||||
|
||||
for (int i = 0; i < enumValues.Length; i++) { |
||||
yield return new StandardValue() { |
||||
Instance = enumValues.GetValue(i), |
||||
Text = enumNames[i], |
||||
}; |
||||
} |
||||
} |
||||
List<StandardValue> values; |
||||
lock (standardValues) { |
||||
if (standardValues.TryGetValue(type, out values)) { |
||||
foreach (var value in values) { |
||||
if (value.Text == null) { |
||||
if (Runtime.TryConvertToText(null, value.Instance, out value.Text)) { |
||||
yield return value; |
||||
} |
||||
} |
||||
else { |
||||
yield return value; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
var converter = TypeDescriptor.GetConverter(type); |
||||
if (converter.GetStandardValuesSupported()) { |
||||
foreach (var value in converter.GetStandardValues()) { |
||||
string text; |
||||
if (Runtime.TryConvertToText(null, value, out text)) { |
||||
yield return new StandardValue() { |
||||
Instance = value, |
||||
Text = text |
||||
}; |
||||
} |
||||
} |
||||
} |
||||
yield break; |
||||
} |
||||
|
||||
public static string GetStandardValueText(object value) |
||||
{ |
||||
lock (standardValueFromInstance) { |
||||
StandardValue standardValue; |
||||
if (standardValueFromInstance.TryGetValue(value, out standardValue)) { |
||||
return standardValue.Text; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
//static Dictionary<Type, Type> designTimeTypes = new Dictionary<Type, Type>();
|
||||
|
||||
//public static void AddDesignTimeType(Type type, Type designTimeType)
|
||||
//{
|
||||
// lock (designTimeTypes)
|
||||
// {
|
||||
// designTimeTypes[type] = designTimeType;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public static Type GetDesignTimeType(Type type)
|
||||
//{
|
||||
// lock (designTimeTypes)
|
||||
// {
|
||||
// Type result;
|
||||
// if (designTimeTypes.TryGetValue(type, out result))
|
||||
// {
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
// return type;
|
||||
//}
|
||||
} |
||||
|
||||
public class StandardValue |
||||
{ |
||||
public object Instance; |
||||
public string Text; |
||||
} |
||||
} |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Diagnostics; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class TextNode : XamlValue |
||||
{ |
||||
internal TextNode() |
||||
{ |
||||
} |
||||
|
||||
public string Text; |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return GetType().Name + ": " + Text; |
||||
} |
||||
|
||||
public override IEnumerable<XamlNode> Nodes() |
||||
{ |
||||
yield break; |
||||
} |
||||
|
||||
protected override void RemoveChild(XamlNode node) |
||||
{ |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class Tracker |
||||
{ |
||||
public virtual void Process(DocumentChangedEventArgs e) |
||||
{ |
||||
Remove(e.OldNode, e.OldParent); |
||||
Add(e.NewNode); |
||||
} |
||||
|
||||
public virtual void Add(XamlNode node) |
||||
{ |
||||
if (node is MemberNode) { |
||||
Add(node as MemberNode); |
||||
} |
||||
else if (node is ObjectNode) { |
||||
Add(node as ObjectNode); |
||||
} |
||||
else if (node is TextNode) { |
||||
Add(node as TextNode); |
||||
} |
||||
} |
||||
|
||||
public virtual void Add(MemberNode node) |
||||
{ |
||||
} |
||||
|
||||
public virtual void Add(ObjectNode node) |
||||
{ |
||||
} |
||||
|
||||
public virtual void Add(TextNode node) |
||||
{ |
||||
} |
||||
|
||||
public virtual void Remove(XamlNode node, XamlNode parent) |
||||
{ |
||||
if (node is MemberNode) { |
||||
Remove(node as MemberNode, parent as ObjectNode); |
||||
} |
||||
else if (node is ObjectNode) { |
||||
Remove(node as ObjectNode, parent as MemberNode); |
||||
} |
||||
else if (node is TextNode) { |
||||
Remove(node as TextNode, parent as MemberNode); |
||||
} |
||||
} |
||||
|
||||
public virtual void Remove(MemberNode node, ObjectNode parent) |
||||
{ |
||||
} |
||||
|
||||
public virtual void Remove(ObjectNode node, MemberNode parent) |
||||
{ |
||||
} |
||||
|
||||
public virtual void Remove(TextNode node, MemberNode parent) |
||||
{ |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Xaml |
||||
{ |
||||
class XamlValueCollection |
||||
{ |
||||
} |
||||
} |
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using ICSharpCode.Xaml; |
||||
using System.Windows; |
||||
using System.Windows.Markup; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class WpfTracker : Tracker |
||||
{ |
||||
} |
||||
} |
@ -0,0 +1,119 @@
@@ -0,0 +1,119 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<ProductVersion>9.0.30729</ProductVersion> |
||||
<SchemaVersion>2.0</SchemaVersion> |
||||
<ProjectGuid>{B4E5C965-7BB9-4AE9-85FB-C47480B879AD}</ProjectGuid> |
||||
<OutputType>Library</OutputType> |
||||
<AppDesignerFolder>Properties</AppDesignerFolder> |
||||
<RootNamespace>ICSharpCode.Xaml</RootNamespace> |
||||
<AssemblyName>ICSharpCode.Xaml</AssemblyName> |
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> |
||||
<FileAlignment>512</FileAlignment> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>full</DebugType> |
||||
<Optimize>false</Optimize> |
||||
<OutputPath>..\..\..\..\..\AddIns\AddIns\BackendBindings\XamlBinding\</OutputPath> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
<ErrorReport>prompt</ErrorReport> |
||||
<WarningLevel>4</WarningLevel> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
||||
<DebugType>pdbonly</DebugType> |
||||
<Optimize>true</Optimize> |
||||
<OutputPath>bin\Release\</OutputPath> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
<ErrorReport>prompt</ErrorReport> |
||||
<WarningLevel>4</WarningLevel> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="PresentationCore"> |
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="PresentationFramework"> |
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Core"> |
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System.Xml.Linq"> |
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System.Data.DataSetExtensions"> |
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System.Data" /> |
||||
<Reference Include="System.Xml" /> |
||||
<Reference Include="WindowsBase"> |
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
||||
</Reference> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="..\..\..\..\Main\GlobalAssemblyInfo.cs"> |
||||
<Link>Properties\GlobalAssemblyInfo.cs</Link> |
||||
</Compile> |
||||
<Compile Include="AllowedLocation.cs" /> |
||||
<Compile Include="CollectionSupport.cs" /> |
||||
<Compile Include="Constructor.cs" /> |
||||
<Compile Include="DefaultXamlMember.cs" /> |
||||
<Compile Include="DefaultXamlType.cs" /> |
||||
<Compile Include="Directive.cs" /> |
||||
<Compile Include="InstanceTracker.cs"> |
||||
<SubType>Code</SubType> |
||||
</Compile> |
||||
<Compile Include="Runtime.cs"> |
||||
<SubType>Code</SubType> |
||||
</Compile> |
||||
<Compile Include="StandardValues.cs"> |
||||
<SubType>Code</SubType> |
||||
</Compile> |
||||
<Compile Include="Tracker.cs" /> |
||||
<Compile Include="ExtensionMethods.cs" /> |
||||
<Compile Include="IHasAnnotations.cs" /> |
||||
<Compile Include="IntristicMember.cs" /> |
||||
<Compile Include="IntristicType.cs" /> |
||||
<Compile Include="MarkupExtensionParser.cs" /> |
||||
<Compile Include="MemberNode.cs" /> |
||||
<Compile Include="NodeCollection.cs" /> |
||||
<Compile Include="ObjectNode.cs" /> |
||||
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||
<Compile Include="ReflectionAssembly.cs" /> |
||||
<Compile Include="ReflectionMember.cs" /> |
||||
<Compile Include="ReflectionMemberInfo.cs" /> |
||||
<Compile Include="ReflectionMapper.cs" /> |
||||
<Compile Include="ReflectionType.cs" /> |
||||
<Compile Include="XamlContext.cs" /> |
||||
<Compile Include="TextNode.cs" /> |
||||
<Compile Include="XamlFormatter.cs" /> |
||||
<Compile Include="XamlProject.cs" /> |
||||
<Compile Include="XamlAssembly.cs" /> |
||||
<Compile Include="XamlConstants.cs" /> |
||||
<Compile Include="XamlDocument.cs" /> |
||||
<Compile Include="XamlDocumentError.cs" /> |
||||
<Compile Include="XamlException.cs" /> |
||||
<Compile Include="XamlMember.cs" /> |
||||
<Compile Include="XamlNode.cs" /> |
||||
<Compile Include="XamlParser.cs" /> |
||||
<Compile Include="XamlProperty.cs" /> |
||||
<Compile Include="XamlType.cs" /> |
||||
<Compile Include="XamlTypeFinder.cs" /> |
||||
<Compile Include="XamlValue.cs" /> |
||||
<Compile Include="XmlnsDefinition.cs" /> |
||||
<Compile Include="XmlTracker.cs"> |
||||
<SubType>Code</SubType> |
||||
</Compile> |
||||
</ItemGroup> |
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
||||
Other similar extension points exist, see Microsoft.Common.targets. |
||||
<Target Name="BeforeBuild"> |
||||
</Target> |
||||
<Target Name="AfterBuild"> |
||||
</Target> |
||||
--> |
||||
</Project> |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Windows.Markup; |
||||
using System.Diagnostics; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
[DebuggerDisplay("{Name}")] |
||||
public abstract class XamlAssembly |
||||
{ |
||||
//public abstract XamlType[] Types;
|
||||
public abstract IEnumerable<XmlnsDefinitionAttribute> XmlnsDefinitions { get; } |
||||
public abstract string Name { get; } |
||||
public abstract XamlType GetType(string fullName); |
||||
} |
||||
} |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Xml.Linq; |
||||
using System.Reflection; |
||||
using System.Windows; |
||||
using System.IO; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class XamlConstants |
||||
{ |
||||
public static XNamespace XamlNamespace = "http://schemas.microsoft.com/winfx/2006/xaml"; |
||||
public static XNamespace Presentation2006Namespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"; |
||||
public static XNamespace Presentation2007Namespace = "http://schemas.microsoft.com/netfx/2007/xaml/presentation"; |
||||
|
||||
public static Assembly MscorlibAssembly = typeof(object).Assembly; |
||||
public static Assembly WindowsBaseAssembly = typeof(DependencyObject).Assembly; |
||||
public static Assembly PresentationCoreAssembly = typeof(UIElement).Assembly; |
||||
public static Assembly PresentationFrameworkAssembly = typeof(FrameworkElement).Assembly; |
||||
|
||||
public static XName XmlSpaceName = XNamespace.Xml.GetName("space"); |
||||
|
||||
public static bool HasXamlExtension(string filePath) |
||||
{ |
||||
return Path.GetExtension(filePath).Equals(".xaml", StringComparison.InvariantCultureIgnoreCase); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,130 @@
@@ -0,0 +1,130 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.ComponentModel; |
||||
using System.Windows.Markup; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class XamlContext : IServiceProvider, ITypeDescriptorContext, IXamlTypeResolver, IUriContext, IProvideValueTarget, IValueSerializerContext |
||||
{ |
||||
internal XamlContext(XamlProperty property) |
||||
{ |
||||
this.property = property; |
||||
} |
||||
|
||||
XamlProperty property; |
||||
|
||||
public XamlProperty XamlProperty |
||||
{ |
||||
get { return property; } |
||||
} |
||||
|
||||
#region IServiceProvider Members
|
||||
|
||||
public object GetService(Type serviceType) |
||||
{ |
||||
if (serviceType == typeof(ITypeDescriptorContext)) return this; |
||||
if (serviceType == typeof(IXamlTypeResolver)) return this; |
||||
if (serviceType == typeof(IUriContext)) return this; |
||||
if (serviceType == typeof(IProvideValueTarget)) return this; |
||||
if (serviceType == typeof(IValueSerializerContext)) return this; |
||||
return null; |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
#region ITypeDescriptorContext Members
|
||||
|
||||
public IContainer Container |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public object Instance |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
public void OnComponentChanged() |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public bool OnComponentChanging() |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public PropertyDescriptor PropertyDescriptor |
||||
{ |
||||
get { throw new NotImplementedException(); } |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
#region IXamlTypeResolver Members
|
||||
|
||||
public Type Resolve(string qualifiedTypeName) |
||||
{ |
||||
var namespaceProvider = XmlTracker.GetNamespaceProvider(property.Object); |
||||
var typeName = XamlParser.GetTypeName(qualifiedTypeName, namespaceProvider); |
||||
var type = property.Object.Document.Project.TypeFinder.FindType(typeName); |
||||
return type.SystemType; |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
#region IUriContext Members
|
||||
|
||||
public Uri BaseUri |
||||
{ |
||||
get |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
set |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
#region IProvideValueTarget Members
|
||||
|
||||
public object TargetObject |
||||
{ |
||||
get { return property.Object.Instance; } |
||||
} |
||||
|
||||
public object TargetProperty |
||||
{ |
||||
get |
||||
{ |
||||
var reflectionMember = property.Member as ReflectionMember; |
||||
if (reflectionMember != null) { |
||||
return reflectionMember.Info.DependencyProperty; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
#region IValueSerializerContext Members
|
||||
|
||||
public ValueSerializer GetValueSerializerFor(PropertyDescriptor descriptor) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public ValueSerializer GetValueSerializerFor(Type type) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
#endregion
|
||||
} |
||||
} |
@ -0,0 +1,152 @@
@@ -0,0 +1,152 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Xml; |
||||
using System.Xml.Linq; |
||||
using System.Diagnostics; |
||||
using System.Windows.Markup; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class XamlDocument : IUriContext |
||||
{ |
||||
internal XamlDocument(XamlProject project) |
||||
{ |
||||
Project = project; |
||||
Parser = new XamlParser(this); |
||||
Trackers.Add(new InstanceTracker()); |
||||
Trackers.Add(new XmlTracker()); |
||||
} |
||||
|
||||
public XamlParser Parser { get; private set; } |
||||
public XamlProject Project { get; private set; } |
||||
public List<XamlDocument> Dependencies = new List<XamlDocument>(); |
||||
public List<XamlDocumentError> Errors = new List<XamlDocumentError>(); |
||||
public List<Tracker> Trackers = new List<Tracker>(); |
||||
public XDocument XmlDocument; |
||||
|
||||
public event EventHandler RootChanged; |
||||
public event DocumentChangedEventHandler DocumentChanged; |
||||
|
||||
bool parsing; |
||||
|
||||
ObjectNode root; |
||||
|
||||
public ObjectNode Root |
||||
{ |
||||
get |
||||
{ |
||||
return root; |
||||
} |
||||
set |
||||
{ |
||||
var e = new DocumentChangedEventArgs() { OldNode = root, NewNode = value }; |
||||
root = value; |
||||
RaiseDocumentChanged(e); |
||||
|
||||
if (RootChanged != null) { |
||||
RootChanged(this, EventArgs.Empty); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public ObjectNode ParseObject(string text) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public ObjectNode CreateObject(object instance) |
||||
{ |
||||
return new ObjectNode(this, instance); |
||||
} |
||||
|
||||
public void Parse(string text) |
||||
{ |
||||
ObjectNode result = null; |
||||
Errors.Clear(); |
||||
parsing = true; |
||||
|
||||
try { |
||||
XmlDocument = XDocument.Parse(text); |
||||
result = Parser.CreateObjectNodeFromXmlElement(XmlDocument.Root, false); |
||||
foreach (var node in result.DescendantsAndSelf()) { |
||||
node.Document = this; |
||||
} |
||||
} |
||||
catch (Exception x) { |
||||
} |
||||
|
||||
parsing = false; |
||||
Root = result; |
||||
} |
||||
|
||||
public bool CanSave |
||||
{ |
||||
get { return XmlDocument != null; } |
||||
} |
||||
|
||||
public string Save() |
||||
{ |
||||
//return XamlFormatter.Format(XmlDocument.ToString());
|
||||
|
||||
var settings = new XmlWriterSettings() { |
||||
Indent = true, |
||||
IndentChars = " ", |
||||
NewLineOnAttributes = true, |
||||
OmitXmlDeclaration = true |
||||
}; |
||||
var sb = new StringBuilder(); |
||||
using (var writer = XmlWriter.Create(sb, settings)) { |
||||
XmlDocument.WriteTo(writer); |
||||
} |
||||
|
||||
return sb.ToString(); |
||||
} |
||||
|
||||
internal void RaiseDocumentChanged(DocumentChangedEventArgs e) |
||||
{ |
||||
if (!parsing) { |
||||
foreach (var t in Trackers) { |
||||
t.Process(e); |
||||
} |
||||
if (DocumentChanged != null) { |
||||
DocumentChanged(this, e); |
||||
} |
||||
} |
||||
} |
||||
|
||||
#region IUriContext Members
|
||||
|
||||
Uri baseUri; |
||||
|
||||
public Uri BaseUri |
||||
{ |
||||
get |
||||
{ |
||||
return baseUri; |
||||
} |
||||
set |
||||
{ |
||||
if (baseUri != null) { |
||||
Project.Documents.Remove(baseUri); |
||||
} |
||||
baseUri = value; |
||||
if (baseUri != null) { |
||||
Project.Documents[baseUri] = this; |
||||
} |
||||
} |
||||
} |
||||
|
||||
#endregion
|
||||
} |
||||
|
||||
public delegate void DocumentChangedEventHandler(object sender, DocumentChangedEventArgs e); |
||||
|
||||
public class DocumentChangedEventArgs : EventArgs |
||||
{ |
||||
public XamlNode OldNode; |
||||
public XamlNode OldParent; |
||||
public XamlNode NewNode; |
||||
} |
||||
} |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class XamlDocumentError |
||||
{ |
||||
public string Message { get; set; } |
||||
public int LineNumber { get; set; } |
||||
public int LinePosition { get; set; } |
||||
public XamlDocument Document { get; set; } |
||||
} |
||||
} |
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Runtime.Serialization; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
[Serializable] |
||||
public class XamlException : Exception |
||||
{ |
||||
public XamlException() |
||||
{ |
||||
} |
||||
|
||||
public XamlException(string message) |
||||
: base(message) |
||||
{ |
||||
} |
||||
|
||||
public XamlException(string message, Exception innerException) |
||||
: base(message, innerException) |
||||
{ |
||||
} |
||||
|
||||
protected XamlException(SerializationInfo info, StreamingContext context) |
||||
: base(info, context) |
||||
{ |
||||
} |
||||
|
||||
public int LineNumber { get; set; } |
||||
public int LinePosition { get; set; } |
||||
public Uri BaseUri { get; set; } |
||||
} |
||||
} |
@ -0,0 +1,210 @@
@@ -0,0 +1,210 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Xml.Linq; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
//TODO: formatter should be based on XamlDocument
|
||||
public static class XamlFormatter |
||||
{ |
||||
public static char IndentChar = ' '; |
||||
public static int Indenation = 2; |
||||
public static int LengthBeforeNewLine = 60; |
||||
|
||||
static StringBuilder sb; |
||||
static int currentColumn; |
||||
static int nextColumn; |
||||
|
||||
public static string Format(string xaml) |
||||
{ |
||||
sb = new StringBuilder(); |
||||
currentColumn = 0; |
||||
nextColumn = 0; |
||||
|
||||
try { |
||||
var doc = XDocument.Parse(xaml); |
||||
WalkContainer(doc); |
||||
return sb.ToString(); |
||||
} |
||||
catch { |
||||
return xaml; |
||||
} |
||||
} |
||||
|
||||
static void WalkContainer(XContainer node) |
||||
{ |
||||
foreach (var c in node.Nodes()) { |
||||
if (c is XElement) { |
||||
WalkElement(c as XElement); |
||||
} |
||||
else { |
||||
NewLine(); |
||||
Append(c.ToString().Trim()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void WalkElement(XElement e) |
||||
{ |
||||
NewLine(); |
||||
string prefix1 = e.GetPrefixOfNamespace(e.Name.Namespace); |
||||
string name1 = prefix1 == null ? e.Name.LocalName : prefix1 + ":" + e.Name.LocalName; |
||||
Append("<" + name1); |
||||
|
||||
List<AttributeString> list = new List<AttributeString>(); |
||||
int length = name1.Length; |
||||
|
||||
foreach (var a in e.Attributes()) { |
||||
string prefix2 = e.GetPrefixOfNamespace(a.Name.Namespace); |
||||
var g = new AttributeString() { Name = a.Name, Prefix = prefix2, Value = a.Value }; |
||||
list.Add(g); |
||||
length += g.FinalString.Length; |
||||
} |
||||
|
||||
list.Sort(AttributeComparrer.Instance); |
||||
|
||||
if (length > LengthBeforeNewLine) { |
||||
nextColumn = currentColumn + 1; |
||||
for (int i = 0; i < list.Count; i++) { |
||||
if (i > 0) { |
||||
NewLine(); |
||||
} |
||||
else { |
||||
Append(" "); |
||||
} |
||||
Append(list[i].FinalString); |
||||
} |
||||
nextColumn -= name1.Length + 2; |
||||
} |
||||
else { |
||||
foreach (var a in list) { |
||||
Append(" " + a.FinalString); |
||||
} |
||||
} |
||||
|
||||
if (e.Nodes().Count() > 0) { |
||||
Append(">"); |
||||
nextColumn += Indenation; |
||||
|
||||
WalkContainer(e); |
||||
|
||||
nextColumn -= Indenation; |
||||
NewLine(); |
||||
Append("</" + name1 + ">"); |
||||
} |
||||
else { |
||||
Append(" />"); |
||||
} |
||||
} |
||||
|
||||
static void NewLine() |
||||
{ |
||||
if (sb.Length > 0) { |
||||
sb.AppendLine(); |
||||
sb.Append(new string(' ', nextColumn)); |
||||
currentColumn = nextColumn; |
||||
} |
||||
} |
||||
|
||||
static void Append(string s) |
||||
{ |
||||
sb.Append(s); |
||||
currentColumn += s.Length; |
||||
} |
||||
|
||||
enum AttributeLayout |
||||
{ |
||||
X, |
||||
XmlnsMicrosoft, |
||||
Xmlns, |
||||
XmlnsWithClr, |
||||
SpecialOrder, |
||||
ByName, |
||||
Attached, |
||||
WithPrefix |
||||
} |
||||
|
||||
class AttributeString |
||||
{ |
||||
public XName Name; |
||||
public string Prefix; |
||||
public string Value; |
||||
|
||||
public string LocalName |
||||
{ |
||||
get { return Name.LocalName; } |
||||
} |
||||
|
||||
public string FinalName |
||||
{ |
||||
get |
||||
{ |
||||
return Prefix == null ? Name.LocalName : Prefix + ":" + Name.LocalName; |
||||
} |
||||
} |
||||
|
||||
public string FinalString |
||||
{ |
||||
get |
||||
{ |
||||
return FinalName + "=\"" + Value + "\""; |
||||
} |
||||
} |
||||
|
||||
public AttributeLayout GetAttributeLayout() |
||||
{ |
||||
if (Prefix == "xmlns" || LocalName == "xmlns") { |
||||
if (Value.StartsWith("http://schemas.microsoft.com")) return AttributeLayout.XmlnsMicrosoft; |
||||
if (Value.StartsWith("clr")) return AttributeLayout.XmlnsWithClr; |
||||
return AttributeLayout.Xmlns; |
||||
} |
||||
if (Prefix == "x") return AttributeLayout.X; |
||||
if (Prefix != null) return AttributeLayout.WithPrefix; |
||||
if (LocalName.Contains(".")) return AttributeLayout.Attached; |
||||
if (AttributeComparrer.SpecialOrder.Contains(LocalName)) return AttributeLayout.SpecialOrder; |
||||
return AttributeLayout.ByName; |
||||
} |
||||
} |
||||
|
||||
class AttributeComparrer : IComparer<AttributeString> |
||||
{ |
||||
public static AttributeComparrer Instance = new AttributeComparrer(); |
||||
|
||||
public int Compare(AttributeString a1, AttributeString a2) |
||||
{ |
||||
var y1 = a1.GetAttributeLayout(); |
||||
var y2 = a2.GetAttributeLayout(); |
||||
if (y1 == y2) { |
||||
if (y1 == AttributeLayout.SpecialOrder) { |
||||
return |
||||
Array.IndexOf(SpecialOrder, a1.LocalName).CompareTo( |
||||
Array.IndexOf(SpecialOrder, a2.LocalName)); |
||||
} |
||||
return a1.FinalName.CompareTo(a2.FinalName); |
||||
} |
||||
return y1.CompareTo(y2); |
||||
} |
||||
|
||||
public static string[] SpecialOrder = new string[] { |
||||
"Name", |
||||
"Content", |
||||
"Command", |
||||
"Executed", |
||||
"CanExecute", |
||||
"Width", |
||||
"Height", |
||||
"Margin", |
||||
"HorizontalAlignment", |
||||
"VerticalAlignment", |
||||
"HorizontalContentAlignment", |
||||
"VerticalContentAlignment", |
||||
"StartPoint", |
||||
"EndPoint", |
||||
"Offset", |
||||
"Color" |
||||
}; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Diagnostics; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public abstract class XamlMember |
||||
{ |
||||
public abstract string Name { get; } |
||||
public abstract XamlType OwnerType { get; } |
||||
public abstract XamlType ValueType { get; } |
||||
public abstract bool IsReadOnly { get; } |
||||
public abstract bool IsStatic { get; } |
||||
public abstract bool IsAttachable { get; } |
||||
public abstract XamlType TargetType { get; } |
||||
public abstract AllowedLocation AllowedLocation { get; } |
||||
public abstract bool IsEvent { get; } |
||||
public abstract bool IsDirective { get; } |
||||
public abstract bool HasTextSyntax { get; } |
||||
|
||||
public bool IsNameProperty |
||||
{ |
||||
get |
||||
{ |
||||
return this == Directive.Name || this == OwnerType.NameProperty; |
||||
} |
||||
} |
||||
|
||||
public abstract T GetAttribute<T>() where T : Attribute; |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return GetType().Name + ": " + Name; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Xml.Linq; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public abstract class XamlNode : IHasAnnotations |
||||
{ |
||||
public XamlNode ParentNode; |
||||
public XamlDocument Document; |
||||
public XObject XmlObject; |
||||
|
||||
public abstract IEnumerable<XamlNode> Nodes(); |
||||
protected abstract void RemoveChild(XamlNode node); |
||||
|
||||
public bool InDocument |
||||
{ |
||||
get { return FindAncestor(n => Document.Root == n) != null; } |
||||
} |
||||
|
||||
public IEnumerable<XamlNode> Descendants() |
||||
{ |
||||
foreach (var node in Nodes()) { |
||||
foreach (var node2 in node.DescendantsAndSelf()) { |
||||
yield return node2; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<XamlNode> DescendantsAndSelf() |
||||
{ |
||||
foreach (var node in Descendants()) { |
||||
yield return node; |
||||
} |
||||
yield return this; |
||||
} |
||||
|
||||
public XamlNode FindAncestor(Predicate<XamlNode> predicate) |
||||
{ |
||||
var node = this; |
||||
while (node != null) { |
||||
if (predicate(node)) { |
||||
return node; |
||||
} |
||||
node = node.ParentNode; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public void Remove() |
||||
{ |
||||
ParentNode.RemoveChild(this); |
||||
} |
||||
|
||||
#region IHasAnnotations Members
|
||||
|
||||
Dictionary<Type, object> annotations = new Dictionary<Type, object>(); |
||||
|
||||
public void AnnotateWith<T>(T annotation) where T : class |
||||
{ |
||||
annotations[typeof(T)] = annotation; |
||||
} |
||||
|
||||
public T GetAnnotation<T>() where T : class |
||||
{ |
||||
object result; |
||||
if (annotations.TryGetValue(typeof(T), out result)) { |
||||
return (T)result; |
||||
} |
||||
return default(T); |
||||
} |
||||
|
||||
#endregion
|
||||
} |
||||
} |
@ -0,0 +1,637 @@
@@ -0,0 +1,637 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Xml.Linq; |
||||
using System.Text.RegularExpressions; |
||||
using System.Windows.Data; |
||||
using System.Collections; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class XamlParser |
||||
{ |
||||
public XamlParser(XamlDocument doc) |
||||
{ |
||||
Document = doc; |
||||
} |
||||
|
||||
public XamlDocument Document { get; private set; } |
||||
|
||||
public XamlTypeFinder TypeFinder |
||||
{ |
||||
get { return Document.Project.TypeFinder; } |
||||
} |
||||
|
||||
public ObjectNode CreateObjectNodeFromXmlElement(XElement xmlObjectElement, |
||||
bool parentPreservesXmlSpace) |
||||
{ |
||||
//type
|
||||
XamlType objectType = TypeFinder.FindType(xmlObjectElement.Name); |
||||
if (objectType == null) { |
||||
objectType = TypeFinder.FindExtensionType(xmlObjectElement.Name); |
||||
} |
||||
if (objectType == null) { |
||||
throw new XamlException("Unknown element type"); |
||||
} |
||||
|
||||
//xml:space
|
||||
bool preserveChildXmlSpace = parentPreservesXmlSpace; |
||||
var spaceAttribute = xmlObjectElement.Attribute(XamlConstants.XmlSpaceName); |
||||
if (spaceAttribute != null) { |
||||
preserveChildXmlSpace = spaceAttribute.Value == "preserve"; |
||||
} |
||||
|
||||
//x:Code, x:XData
|
||||
if (objectType == IntristicType.Code || objectType == IntristicType.XData) { |
||||
ObjectNode literalResult = new ObjectNode(); |
||||
literalResult.Type = objectType; |
||||
var textNode = new TextNode() { Text = xmlObjectElement.Value }; |
||||
var memberNode = new MemberNode(); |
||||
memberNode.Values.Add(textNode); |
||||
literalResult.MemberNodes.Add(memberNode); |
||||
literalResult.XmlObject = xmlObjectElement; |
||||
return literalResult; |
||||
} |
||||
|
||||
List<XamlNode> convertedChildNodes = new List<XamlNode>(); |
||||
List<ObjectNode> codeItems = new List<ObjectNode>(); |
||||
|
||||
//conversion
|
||||
|
||||
foreach (var node in xmlObjectElement.Nodes()) { |
||||
var childElement = node as XElement; |
||||
if (childElement != null) { |
||||
if (IsXamlName(childElement.Name)) { |
||||
var convertedObject = CreateObjectNodeFromXmlElement(childElement, preserveChildXmlSpace); |
||||
if (convertedObject.Type == IntristicType.Code) { |
||||
codeItems.Add(convertedObject); |
||||
} |
||||
else { |
||||
convertedChildNodes.Add(convertedObject); |
||||
} |
||||
} |
||||
else if (GetDottedXamlName(childElement.Name) != null) { |
||||
var convertedMember = CreateMemberNodeFromXmlElement(childElement, objectType, preserveChildXmlSpace); |
||||
foreach (var objectNode in convertedMember.Values.OfType<ObjectNode>().ToArray()) { |
||||
if (objectNode.Type == IntristicType.Code) { |
||||
codeItems.Add(objectNode); |
||||
convertedMember.Values.Remove(objectNode); |
||||
} |
||||
} |
||||
convertedChildNodes.Add(convertedMember); |
||||
} |
||||
else { |
||||
throw new XamlException("Invalid element name syntax"); |
||||
} |
||||
} |
||||
else { |
||||
AddText(convertedChildNodes, node); |
||||
} |
||||
} |
||||
|
||||
if (codeItems.Count > 0) { |
||||
MemberNode directiveChildren = new MemberNode(); |
||||
directiveChildren.Member = IntristicMember.DirectiveChildren; |
||||
foreach (var item in codeItems) { |
||||
directiveChildren.Values.Add(item); |
||||
//item.ParentMember = directiveChildren;
|
||||
} |
||||
|
||||
} |
||||
|
||||
//whitespace removal
|
||||
|
||||
List<XamlNode> strippedChildNodes = new List<XamlNode>(); |
||||
int n = convertedChildNodes.Count; |
||||
bool hasTextNodes = false; |
||||
bool hasContent = false; |
||||
|
||||
for (int i = 0; i < n; i++) { |
||||
var node = convertedChildNodes[i]; |
||||
var textNode = node as TextNode; |
||||
if (textNode != null && IsCollapsibleString(textNode.Text)) { |
||||
bool prevMember = i - 1 > 0 && convertedChildNodes[i - 1] is MemberNode; |
||||
bool nextMember = i + 1 < n && convertedChildNodes[i + 1] is MemberNode; |
||||
if (i == 0 && nextMember) continue; |
||||
if (prevMember && nextMember) continue; |
||||
if (i == n - 1 && prevMember && (hasTextNodes || hasContent)) continue; |
||||
} |
||||
|
||||
strippedChildNodes.Add(convertedChildNodes[i]); |
||||
|
||||
if (textNode != null) { |
||||
hasTextNodes = true; |
||||
} |
||||
var memberNode = node as MemberNode; |
||||
if (memberNode != null && memberNode.Member == objectType.ContentProperty) { |
||||
hasContent = true; |
||||
} |
||||
} |
||||
|
||||
//content wrapping
|
||||
|
||||
XamlMember contentMember = null; |
||||
XamlType contentMemberType = null; |
||||
if (objectType.ContentProperty != null) { |
||||
contentMember = objectType.ContentProperty; |
||||
contentMemberType = contentMember.ValueType; |
||||
} |
||||
else { |
||||
contentMember = IntristicMember.Items; |
||||
contentMemberType = objectType; |
||||
} |
||||
|
||||
List<MemberNode> attributeMembers = new List<MemberNode>(); |
||||
foreach (var xmlAttribute in xmlObjectElement.Attributes()) { |
||||
if (xmlAttribute.IsNamespaceDeclaration) continue; |
||||
var memberNode = CreateMemberNodeFromXmlAttribute(xmlAttribute, objectType, xmlObjectElement); |
||||
attributeMembers.Add(memberNode); |
||||
} |
||||
|
||||
List<MemberNode> members = new List<MemberNode>(); |
||||
|
||||
bool initFromText = |
||||
strippedChildNodes.Count(node => node is TextNode) == 1 && |
||||
strippedChildNodes.All(node => node is TextNode || |
||||
node is MemberNode && (node as MemberNode).Member == IntristicMember.DirectiveChildren) && |
||||
attributeMembers.All(node => node.Member == Directive.Key || |
||||
node.Member == Directive.Uid) && |
||||
|
||||
// differ from spec (spec bug?)
|
||||
//(contentMember.HasTextSyntax || objectType.HasTextSyntax);
|
||||
objectType.HasTextSyntax; |
||||
|
||||
if (initFromText) { |
||||
var initTextMember = new MemberNode(); |
||||
initTextMember.Member = IntristicMember.InitializationText; |
||||
initTextMember.Values.Add(strippedChildNodes.OfType<TextNode>().First()); |
||||
members.Add(initTextMember); |
||||
} |
||||
else { |
||||
members.AddRange(attributeMembers); |
||||
List<XamlValue> npChildren = new List<XamlValue>(); |
||||
|
||||
foreach (var node in strippedChildNodes) { |
||||
if (node is MemberNode) { |
||||
if (npChildren.Count > 0) { |
||||
var memberNode = CreateMemberNodeFromContent(contentMember, contentMemberType, npChildren, preserveChildXmlSpace); |
||||
members.Add(memberNode); |
||||
npChildren.Clear(); |
||||
} |
||||
members.Add(node as MemberNode); |
||||
} |
||||
else { |
||||
npChildren.Add(node as XamlValue); |
||||
} |
||||
} |
||||
|
||||
if (npChildren.Count > 0) { |
||||
var memberNode = CreateMemberNodeFromContent(contentMember, contentMemberType, npChildren, preserveChildXmlSpace); |
||||
members.Add(memberNode); |
||||
} |
||||
} |
||||
|
||||
ObjectNode result = new ObjectNode(); |
||||
result.Type = objectType; |
||||
foreach (var memberNode in members) { |
||||
result.MemberNodes.Add(memberNode); |
||||
//memberNode.ParentObject = result;
|
||||
} |
||||
result.XmlObject = xmlObjectElement; |
||||
return result; |
||||
} |
||||
|
||||
public MemberNode CreateMemberNodeFromXmlAttribute(XAttribute xmlAttribute, |
||||
XamlType objectType, XElement namespaceProvider) |
||||
{ |
||||
XamlMember member; |
||||
if (IsXamlName(xmlAttribute.Name)) { |
||||
member = objectType.Member(xmlAttribute.Name.LocalName); |
||||
if (member == null) { |
||||
member = Directive.GetDirective(xmlAttribute.Name); |
||||
} |
||||
if (member == null) { |
||||
throw new XamlException("Unknown member"); |
||||
} |
||||
} |
||||
else { |
||||
var dottedName = GetDottedXamlName(xmlAttribute.Name); |
||||
if (dottedName != null) { |
||||
var attributeNamespace = |
||||
xmlAttribute.Name.Namespace != XNamespace.None ? |
||||
xmlAttribute.Name.Namespace : |
||||
namespaceProvider.Name.Namespace; |
||||
|
||||
var definingType = TypeFinder.FindType(attributeNamespace + dottedName.TypeName); |
||||
if (definingType == null) { |
||||
throw new XamlException("Unknown type"); |
||||
} |
||||
member = definingType.Member(dottedName.MemberName); |
||||
if (member == null) { |
||||
throw new XamlException("Unknown member"); |
||||
} |
||||
} |
||||
else { |
||||
throw new XamlException("Invalid attribute syntax"); |
||||
} |
||||
} |
||||
|
||||
XamlValue attributeValue = CreateValueFromAttributeText(xmlAttribute.Value, namespaceProvider); |
||||
|
||||
MemberNode result = new MemberNode(); |
||||
result.Member = member; |
||||
result.Values.Add(attributeValue); |
||||
//attributeValue.ParentMember = result;
|
||||
result.XmlObject = xmlAttribute; |
||||
return result; |
||||
} |
||||
|
||||
public XamlValue CreateValueFromAttributeText(string valueText, XElement namespaceProvider) |
||||
{ |
||||
if (valueText.StartsWith("{}")) { |
||||
return new TextNode() { Text = valueText.Substring(2) }; |
||||
} |
||||
else if (valueText.StartsWith("{")) { |
||||
return CreateObjectNodeFromMarkupExtensionInAttribute(valueText, namespaceProvider); |
||||
} |
||||
return new TextNode() { Text = valueText }; |
||||
} |
||||
|
||||
public MemberNode CreateMemberNodeFromXmlElement(XElement xmlMemberElement, |
||||
XamlType containingType, bool parentPreservesXmlSpace) |
||||
{ |
||||
if (xmlMemberElement.HasAttributes) { |
||||
if (xmlMemberElement.Attributes().Count() > 1 || |
||||
Directive.GetDirective(xmlMemberElement.FirstAttribute.Name) != |
||||
Directive.Uid) { |
||||
throw new XamlException("Member elements cannot contain attributes"); |
||||
} |
||||
} |
||||
|
||||
var dottedName = GetDottedXamlName(xmlMemberElement.Name); |
||||
XamlType ownerType = TypeFinder.FindType(xmlMemberElement.Name.Namespace + dottedName.TypeName); |
||||
if (ownerType == null) { |
||||
throw new XamlException("Unknown element type"); |
||||
} |
||||
|
||||
XamlMember resolvedMember = ownerType.Member(dottedName.MemberName); |
||||
if (resolvedMember == null || resolvedMember.AllowedLocation != AllowedLocation.Any) { |
||||
throw new XamlException("Member not found"); |
||||
} |
||||
|
||||
List<XamlValue> convertedChildNodes = new List<XamlValue>(); |
||||
|
||||
foreach (var node in xmlMemberElement.Nodes()) { |
||||
var childElement = node as XElement; |
||||
if (childElement != null) { |
||||
if (IsXamlName(childElement.Name)) { |
||||
var convertedObject = CreateObjectNodeFromXmlElement(childElement, parentPreservesXmlSpace); |
||||
convertedChildNodes.Add(convertedObject); |
||||
} |
||||
else if (GetDottedXamlName(childElement.Name) != null) { |
||||
throw new XamlException("Member elements may not be nested directly inside of another member element"); |
||||
} |
||||
else { |
||||
throw new XamlException("Invalid element name syntax"); |
||||
} |
||||
} |
||||
else { |
||||
AddText(convertedChildNodes, node); |
||||
} |
||||
} |
||||
|
||||
var result = CreateMemberNodeFromContent(resolvedMember, resolvedMember.ValueType, convertedChildNodes, parentPreservesXmlSpace); |
||||
result.XmlObject = xmlMemberElement; |
||||
return result; |
||||
} |
||||
|
||||
public MemberNode CreateMemberNodeFromContent(XamlMember containingMember, |
||||
XamlType memberType, List<XamlValue> childNodes, bool preserveXmlSpace) |
||||
{ |
||||
if (!preserveXmlSpace) { |
||||
if (memberType.IsWhitespaceSignificantCollection) { |
||||
TextNode prevTextNode = null; |
||||
for (int i = 0; i < childNodes.Count; i++) { |
||||
var node = childNodes[i]; |
||||
var textNode = node as TextNode; |
||||
if (textNode != null) { |
||||
textNode.Text = CollapseWhitespace(textNode.Text); |
||||
if (prevTextNode == null) { |
||||
textNode.Text = textNode.Text.TrimStart(); |
||||
prevTextNode = textNode; |
||||
} |
||||
} |
||||
else { |
||||
var objectNode = node as ObjectNode; |
||||
if (objectNode != null && objectNode.Type.TrimSurroundingWhitespace) { |
||||
var afterTextNode = i + 1 < childNodes.Count ? childNodes[i + 1] as TextNode : null; |
||||
if (prevTextNode != null) { |
||||
prevTextNode.Text = prevTextNode.Text.TrimEnd(); |
||||
} |
||||
if (afterTextNode != null) { |
||||
afterTextNode.Text = afterTextNode.Text.TrimStart(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
if (prevTextNode != null) { |
||||
prevTextNode.Text = prevTextNode.Text.TrimEnd(); |
||||
} |
||||
} |
||||
// differ from spec (spec bug?)
|
||||
else { |
||||
foreach (var textNode in childNodes.OfType<TextNode>()) { |
||||
textNode.Text = CollapseWhitespace(textNode.Text).Trim(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
childNodes = childNodes.Where(node => node is ObjectNode || (node as TextNode).Text.Length > 0).ToList(); |
||||
|
||||
List<XamlValue> outputValues = new List<XamlValue>(); |
||||
var singleObjectNode = childNodes.FirstOrDefault() as ObjectNode; |
||||
var useSingleObjectNode = singleObjectNode != null && memberType.IsAssignableFrom(singleObjectNode.Type); |
||||
|
||||
if (memberType.IsCollection && !useSingleObjectNode) { |
||||
var retrievedContentMember = new MemberNode(); |
||||
retrievedContentMember.Member = IntristicMember.Items; |
||||
foreach (var value in childNodes) { |
||||
retrievedContentMember.Values.Add(value); |
||||
} |
||||
|
||||
var retrievedValue = new ObjectNode(); |
||||
retrievedValue.Type = memberType; |
||||
retrievedValue.MemberNodes.Add(retrievedContentMember); |
||||
retrievedValue.IsRetrieved = true; |
||||
|
||||
outputValues.Add(retrievedValue); |
||||
} |
||||
else { |
||||
outputValues.AddRange(childNodes); |
||||
} |
||||
|
||||
MemberNode result = new MemberNode(); |
||||
result.Member = containingMember; |
||||
foreach (var value in outputValues) { |
||||
result.Values.Add(value); |
||||
//value.ParentMember = result;
|
||||
} |
||||
return result; |
||||
} |
||||
|
||||
public static XName GetTypeName(string typeNameWithPrefix, XElement namespaceProvider) |
||||
{ |
||||
var prefixedName = GetPrefixedName(typeNameWithPrefix); |
||||
if (prefixedName == null) { |
||||
throw new XamlException("Bad type extension name"); |
||||
} |
||||
|
||||
XNamespace typeNamespace = null; |
||||
if (prefixedName.Prefix == null) { |
||||
typeNamespace = namespaceProvider.Name.Namespace; |
||||
} |
||||
else { |
||||
typeNamespace = namespaceProvider.GetNamespaceOfPrefix(prefixedName.Prefix); |
||||
if (typeNamespace == null) { |
||||
throw new XamlException("Unrecognized namespace prefix"); |
||||
} |
||||
} |
||||
|
||||
return typeNamespace + prefixedName.LocalName; |
||||
} |
||||
|
||||
public ObjectNode CreateObjectNodeFromMarkupExtensionInAttribute(string attributeText, |
||||
XElement namespaceProvider) |
||||
{ |
||||
var ast = MarkupExtensionParser.Parse(attributeText); |
||||
|
||||
var prefixedName = GetPrefixedName(ast.TypeName); |
||||
if (prefixedName == null) { |
||||
throw new XamlException("Bad type extension name"); |
||||
} |
||||
|
||||
XNamespace typeNamespace = null; |
||||
if (prefixedName.Prefix == null) { |
||||
typeNamespace = namespaceProvider.Name.Namespace; |
||||
} |
||||
else { |
||||
typeNamespace = namespaceProvider.GetNamespaceOfPrefix(prefixedName.Prefix); |
||||
if (typeNamespace == null) { |
||||
throw new XamlException("Unrecognized namespace prefix"); |
||||
} |
||||
} |
||||
|
||||
XName typeName = typeNamespace + prefixedName.LocalName; |
||||
XamlType extensionType = TypeFinder.FindExtensionType(typeName); |
||||
if (extensionType == null || !IntristicType.MarkupExtension.IsAssignableFrom(extensionType)) { |
||||
extensionType = TypeFinder.FindType(typeName); |
||||
} |
||||
if (extensionType == null || !IntristicType.MarkupExtension.IsAssignableFrom(extensionType)) { |
||||
throw new XamlException("Unknown markup extension"); |
||||
} |
||||
|
||||
List<MemberNode> namedMembers = new List<MemberNode>(); |
||||
foreach (var namedArg in ast.NamedArgs) { |
||||
var memberName = GetPrefixedName(namedArg.Key); |
||||
if (memberName == null) { |
||||
throw new XamlException("Bad member name"); |
||||
} |
||||
|
||||
XNamespace memberNamespace; |
||||
if (prefixedName.Prefix == null) { |
||||
memberNamespace = namespaceProvider.Name.Namespace; |
||||
} |
||||
else { |
||||
memberNamespace = namespaceProvider.GetNamespaceOfPrefix(prefixedName.Prefix); |
||||
if (typeNamespace == null) { |
||||
throw new XamlException("Unrecognized namespace prefix"); |
||||
} |
||||
} |
||||
|
||||
XamlMember member = null; |
||||
if (IsXamlName(memberName.LocalName)) { |
||||
if (memberNamespace != typeNamespace) { |
||||
throw new XamlException("Unknown member"); |
||||
} |
||||
member = extensionType.Member(memberName.LocalName); |
||||
} |
||||
else { |
||||
var dottedName = GetDottedXamlName(memberNamespace + memberName.LocalName); |
||||
if (dottedName != null) { |
||||
var ownerType = TypeFinder.FindType(memberNamespace + dottedName.TypeName); |
||||
if (ownerType == null) { |
||||
throw new XamlException("Unknown type"); |
||||
} |
||||
member = ownerType.Member(dottedName.MemberName); |
||||
} |
||||
} |
||||
|
||||
if (member == null) { |
||||
throw new XamlException("Unknown member"); |
||||
} |
||||
|
||||
var memberValue = CreateValueFromAttributeText(namedArg.Value, namespaceProvider); |
||||
|
||||
var namedMember = new MemberNode(); |
||||
namedMember.Member = member; |
||||
namedMember.Values.Add(memberValue); |
||||
namedMembers.Add(namedMember); |
||||
} |
||||
|
||||
List<string> positionalArgs = ast.PositionalArgs; |
||||
MemberNode positionalArgsMember = null; |
||||
|
||||
if (positionalArgs.Count > 0) { |
||||
Constructor constructorInfo = null; |
||||
foreach (var extensionConstructor in extensionType.Constructors) { |
||||
if (extensionConstructor.Arguments.Length == positionalArgs.Count) { |
||||
constructorInfo = extensionConstructor; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (constructorInfo == null) { |
||||
throw new XamlException( |
||||
string.Format("No constructor for type '{0}' has {1} parameters", extensionType.Name, positionalArgs.Count)); |
||||
} |
||||
|
||||
List<XamlValue> positionalArgValues = new List<XamlValue>(); |
||||
|
||||
for (int i = 0; i < positionalArgs.Count; i++) { |
||||
var positionalArg = positionalArgs[i]; |
||||
var argumentType = constructorInfo.Arguments.ElementAt(i); |
||||
var argValue = CreateValueFromAttributeText(positionalArg, namespaceProvider); |
||||
positionalArgValues.Add(argValue); |
||||
} |
||||
|
||||
if (!MapPositionalArgsToNamedMembers(constructorInfo, positionalArgValues, namedMembers)) { |
||||
positionalArgsMember = new MemberNode(); |
||||
positionalArgsMember.Member = IntristicMember.ConsructorArgs; |
||||
foreach (var value in positionalArgValues) { |
||||
positionalArgsMember.Values.Add(value); |
||||
//value.ParentMember = positionalArgsMember;
|
||||
} |
||||
} |
||||
} |
||||
|
||||
List<MemberNode> allArgs = new List<MemberNode>(); |
||||
allArgs.AddRange(namedMembers); |
||||
if (positionalArgsMember != null) { |
||||
allArgs.Add(positionalArgsMember); |
||||
} |
||||
|
||||
ObjectNode result = new ObjectNode(); |
||||
result.Type = extensionType; |
||||
foreach (var arg in allArgs) { |
||||
result.MemberNodes.Add(arg); |
||||
//arg.ParentObject = result;
|
||||
} |
||||
return result; |
||||
} |
||||
|
||||
static bool MapPositionalArgsToNamedMembers(Constructor ctor, List<XamlValue> positionalArgValues, List<MemberNode> namedMembers) |
||||
{ |
||||
if (ctor.CorrespondingMembers != null) { |
||||
for (int i = 0; i < positionalArgValues.Count; i++) { |
||||
var memberNode = new MemberNode(); |
||||
memberNode.Member = ctor.CorrespondingMembers[i]; |
||||
memberNode.Values.Add(positionalArgValues[i]); |
||||
namedMembers.Add(memberNode); |
||||
} |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static Regex XamlNameRegex = new Regex(@"^[\w]*$"); |
||||
static Regex DottedXamlNameRegex = new Regex(@"^([\w]*)\.([\w]*)$"); |
||||
|
||||
static bool IsXamlName(XName name) |
||||
{ |
||||
return XamlNameRegex.IsMatch(name.LocalName); |
||||
} |
||||
|
||||
static DottedXamlName GetDottedXamlName(XName name) |
||||
{ |
||||
var m = DottedXamlNameRegex.Match(name.LocalName); |
||||
if (m.Success) { |
||||
return new DottedXamlName() { |
||||
TypeName = m.Groups[1].Value, |
||||
MemberName = m.Groups[2].Value |
||||
}; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
static PrefixedName GetPrefixedName(string s) |
||||
{ |
||||
var result = new PrefixedName(); |
||||
var parts = s.Split(':'); |
||||
if (parts.Length == 1) { |
||||
result.LocalName = parts[0]; |
||||
} |
||||
else { |
||||
result.Prefix = parts[0]; |
||||
result.LocalName = parts[1]; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
public static bool IsCollapsibleChar(char c) |
||||
{ |
||||
return char.IsWhiteSpace(c); |
||||
} |
||||
|
||||
public static bool IsCollapsibleString(string s) |
||||
{ |
||||
return s == null || s.Trim().Length == 0; |
||||
} |
||||
|
||||
public static string CollapseWhitespace(string s) |
||||
{ |
||||
StringBuilder b = new StringBuilder(s.Length); |
||||
bool firstSpace = true; |
||||
foreach (var c in s) { |
||||
if (char.IsWhiteSpace(c)) { |
||||
if (firstSpace) b.Append(" "); |
||||
firstSpace = false; |
||||
continue; |
||||
} |
||||
b.Append(c); |
||||
firstSpace = true; |
||||
} |
||||
return b.ToString(); |
||||
} |
||||
|
||||
static void AddText(IList convertedChildNodes, XNode node) |
||||
{ |
||||
var xmlTextNode = node as XText; |
||||
if (xmlTextNode != null) { |
||||
TextNode textNode = null; |
||||
if (convertedChildNodes.Count > 0) { |
||||
textNode = convertedChildNodes[convertedChildNodes.Count - 1] as TextNode; |
||||
} |
||||
if (textNode != null) { |
||||
textNode.Text += xmlTextNode.Value; |
||||
} |
||||
else { |
||||
textNode = new TextNode() { Text = xmlTextNode.Value }; |
||||
convertedChildNodes.Add(textNode); |
||||
} |
||||
} |
||||
} |
||||
|
||||
class DottedXamlName |
||||
{ |
||||
public string TypeName; |
||||
public string MemberName; |
||||
} |
||||
|
||||
class PrefixedName |
||||
{ |
||||
public string Prefix; |
||||
public string LocalName; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,91 @@
@@ -0,0 +1,91 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Reflection; |
||||
using System.Xml.Linq; |
||||
using System.Xml; |
||||
using System.IO; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public abstract class XamlProject |
||||
{ |
||||
public XamlProject() |
||||
{ |
||||
TypeFinder = new XamlTypeFinder(this); |
||||
} |
||||
|
||||
public XamlTypeFinder TypeFinder; |
||||
public XamlAssembly ProjectAssembly; |
||||
public XamlDocument ApplicationDefinition; |
||||
public List<XamlAssembly> References = new List<XamlAssembly>(); |
||||
public List<XamlDocument> Themes = new List<XamlDocument>(); |
||||
public Dictionary<Uri, XamlDocument> Documents = new Dictionary<Uri, XamlDocument>(); |
||||
|
||||
XmlResolver xmlResolver = new XmlUrlResolver(); |
||||
|
||||
public IEnumerable<XamlAssembly> AllAssemblies |
||||
{ |
||||
get |
||||
{ |
||||
if (ProjectAssembly != null) { |
||||
yield return ProjectAssembly; |
||||
} |
||||
foreach (var a in References) { |
||||
yield return a; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public XamlDocument LoadDocument(string uri) |
||||
{ |
||||
var absoluteUri = xmlResolver.ResolveUri(null, uri); |
||||
XamlDocument doc; |
||||
if (!Documents.TryGetValue(absoluteUri, out doc)) { |
||||
doc = new XamlDocument(this); |
||||
var stream = (Stream)xmlResolver.GetEntity(absoluteUri, null, typeof(Stream)); |
||||
var text = new StreamReader(stream).ReadToEnd(); |
||||
doc.Parse(text); |
||||
doc.BaseUri = absoluteUri; |
||||
} |
||||
return doc; |
||||
} |
||||
|
||||
public XamlDocument ParseDocument(string text) |
||||
{ |
||||
var doc = new XamlDocument(this); |
||||
doc.Parse(text); |
||||
return doc; |
||||
} |
||||
|
||||
public XamlDocument CreateDocument() |
||||
{ |
||||
return new XamlDocument(this); |
||||
} |
||||
|
||||
public XamlDocument CreateDocument(object root) |
||||
{ |
||||
var doc = new XamlDocument(this); |
||||
doc.Root = doc.CreateObject(root); |
||||
return doc; |
||||
} |
||||
|
||||
public void AddReference(Assembly assembly) |
||||
{ |
||||
AddReference(ReflectionMapper.GetXamlAssembly(assembly)); |
||||
} |
||||
|
||||
public void AddReference(XamlAssembly xamlAssembly) |
||||
{ |
||||
References.Add(xamlAssembly); |
||||
TypeFinder.RegisterAssembly(xamlAssembly); |
||||
} |
||||
|
||||
public void RemoveReference(Assembly assembly) |
||||
{ |
||||
var xamlAssembly = ReflectionMapper.GetXamlAssembly(assembly); |
||||
References.Remove(xamlAssembly); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,268 @@
@@ -0,0 +1,268 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Xml.Linq; |
||||
using System.Windows.Markup; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class XamlProperty : IHasAnnotations |
||||
{ |
||||
internal XamlProperty(ObjectNode objectNode, XamlMember member) |
||||
{ |
||||
this.objectNode = objectNode; |
||||
this.member = member; |
||||
this.context = new XamlContext(this); |
||||
} |
||||
|
||||
ObjectNode objectNode; |
||||
XamlMember member; |
||||
XamlContext context; |
||||
|
||||
public event EventHandler IsSetChanged; |
||||
public event EventHandler ValueChanged; |
||||
|
||||
public ObjectNode Object |
||||
{ |
||||
get { return objectNode; } |
||||
} |
||||
|
||||
public XamlMember Member |
||||
{ |
||||
get { return member; } |
||||
} |
||||
|
||||
public XamlContext XamlContext |
||||
{ |
||||
get { return context; } |
||||
} |
||||
|
||||
public bool IsSet |
||||
{ |
||||
get { return FindMemberNode() != null; } |
||||
} |
||||
|
||||
public XamlValue Value |
||||
{ |
||||
get |
||||
{ |
||||
var memberNode = FindMemberNode(); |
||||
if (memberNode != null) { |
||||
return memberNode.SingleValue; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public XamlType ValueType |
||||
{ |
||||
get |
||||
{ |
||||
if (member == IntristicMember.InitializationText) { |
||||
return Object.Type; |
||||
} |
||||
return member.ValueType; |
||||
} |
||||
} |
||||
|
||||
public string ValueText |
||||
{ |
||||
get |
||||
{ |
||||
var textValue = Value as TextNode; |
||||
if (textValue != null) { |
||||
return textValue.Text; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public object ValueOnInstance |
||||
{ |
||||
get |
||||
{ |
||||
// TODO: return real value
|
||||
if (Member.IsEvent) { |
||||
return ValueText; |
||||
} |
||||
return Runtime.GetValue(Object.Instance, Member); |
||||
} |
||||
set |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public NodeCollection<XamlValue> Collection |
||||
{ |
||||
get |
||||
{ |
||||
var items = EnsureItems(); |
||||
if (items != null) { |
||||
return items.Values; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public ObjectNode Add(object key, object value) |
||||
{ |
||||
var newObject = AddObject(value); |
||||
newObject.Property(Directive.Key).Set(key); |
||||
return newObject; |
||||
} |
||||
|
||||
public ObjectNode AddObject(object value) |
||||
{ |
||||
return Add(value) as ObjectNode; |
||||
} |
||||
|
||||
public XamlValue Add(object value) |
||||
{ |
||||
var newValue = PrepareValueForCollection(value); |
||||
EnsureItems().Values.Add(newValue); |
||||
return newValue; |
||||
} |
||||
|
||||
public XamlValue Insert(int index, object value) |
||||
{ |
||||
var newValue = PrepareValueForCollection(value); |
||||
EnsureItems().Values.Insert(index, newValue); |
||||
return newValue; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return GetType().Name + ": " + Member.Name; |
||||
} |
||||
|
||||
public ObjectNode SetObject(object value) |
||||
{ |
||||
return Set(value) as ObjectNode; |
||||
} |
||||
|
||||
public TextNode SetText(object value) |
||||
{ |
||||
return Set(value) as TextNode; |
||||
} |
||||
|
||||
public XamlValue Set(object value) |
||||
{ |
||||
if (member.ValueType.IsCollection && !member.ValueType.HasTextSyntax) { |
||||
return AddObject(value); |
||||
} |
||||
else { |
||||
var newValue = PrepareValue(value); |
||||
EnsureMemberNode().SingleValue = newValue; |
||||
return newValue; |
||||
} |
||||
} |
||||
|
||||
public void Reset() |
||||
{ |
||||
var memberNode = FindMemberNode(); |
||||
if (memberNode != null) { |
||||
memberNode.Remove(); |
||||
} |
||||
} |
||||
|
||||
public XamlValue PrepareValue(object value) |
||||
{ |
||||
if (value is XamlValue) { |
||||
return value as XamlValue; |
||||
} |
||||
if (value == null) { |
||||
return new ObjectNode(objectNode.Document, new NullExtension()); |
||||
} |
||||
|
||||
string text = value as string; |
||||
if (text == null) { |
||||
Runtime.TryConvertToText(context, value, out text); |
||||
} |
||||
if (text != null) { |
||||
var namespaceProvider = XmlTracker.GetNamespaceProvider(objectNode); |
||||
var valueNode = objectNode.Document.Parser.CreateValueFromAttributeText(text, namespaceProvider); |
||||
valueNode.Document = objectNode.Document; |
||||
return valueNode; |
||||
} |
||||
|
||||
return new ObjectNode(objectNode.Document, value); |
||||
} |
||||
|
||||
public XamlValue PrepareValueForCollection(object value) |
||||
{ |
||||
var valueNode = PrepareValue(value); |
||||
var textNode = valueNode as TextNode; |
||||
if (textNode != null) { |
||||
var itemsNode = EnsureItems(); |
||||
if (itemsNode.ParentObject != null && |
||||
itemsNode.ParentObject.Type.ContentWrappers.Where( |
||||
t => t.ContentProperty != null && |
||||
t.ContentProperty.ValueType == IntristicType.String).Any()) { |
||||
return textNode; |
||||
} |
||||
|
||||
var wrapperType = Runtime.GetWrapperTypeForInitializationText(value); |
||||
var wrapperNode = new ObjectNode() { |
||||
Document = objectNode.Document, |
||||
Type = wrapperType, |
||||
Instance = value |
||||
}; |
||||
wrapperNode.InitializationText.Set(textNode); |
||||
return wrapperNode; |
||||
} |
||||
return valueNode; |
||||
} |
||||
|
||||
public MemberNode FindMemberNode() |
||||
{ |
||||
return objectNode.FindMemberNode(member); |
||||
} |
||||
|
||||
public MemberNode EnsureMemberNode() |
||||
{ |
||||
return objectNode.EnsureMemberNode(member); |
||||
} |
||||
|
||||
MemberNode EnsureItems() |
||||
{ |
||||
if (member == IntristicMember.Items || |
||||
member == IntristicMember.ConsructorArgs || |
||||
member == IntristicMember.DirectiveChildren) { |
||||
return EnsureMemberNode(); |
||||
} |
||||
|
||||
var memberNode = EnsureMemberNode(); |
||||
if (memberNode.SingleValue == null) { |
||||
var collection = new ObjectNode() { |
||||
Document = objectNode.Document, |
||||
Type = member.ValueType, |
||||
IsRetrieved = true |
||||
}; |
||||
memberNode.SingleValue = collection; |
||||
} |
||||
return (memberNode.SingleValue as ObjectNode).EnsureMemberNode(IntristicMember.Items); |
||||
} |
||||
|
||||
#region IHasAnnotations Members
|
||||
|
||||
Dictionary<Type, object> annotations = new Dictionary<Type, object>(); |
||||
|
||||
public void AnnotateWith<T>(T annotation) where T : class |
||||
{ |
||||
annotations[typeof(T)] = annotation; |
||||
} |
||||
|
||||
public T GetAnnotation<T>() where T : class |
||||
{ |
||||
object result; |
||||
if (annotations.TryGetValue(typeof(T), out result)) { |
||||
return (T)result; |
||||
} |
||||
return default(T); |
||||
} |
||||
|
||||
#endregion
|
||||
} |
||||
} |
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Diagnostics; |
||||
using System.Windows.Markup; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public abstract class XamlType |
||||
{ |
||||
public abstract string Name { get; } |
||||
public abstract bool IsDefaultConstructible { get; } |
||||
public abstract bool IsNullable { get; } |
||||
public abstract IEnumerable<XamlMember> Members { get; } |
||||
public abstract XamlMember ContentProperty { get; } |
||||
public abstract XamlMember DictionaryKeyProperty { get; } |
||||
public abstract XamlMember NameProperty { get; } |
||||
public abstract XamlMember XmlLangProperty { get; } |
||||
public abstract bool TrimSurroundingWhitespace { get; } |
||||
public abstract bool IsWhitespaceSignificantCollection { get; } |
||||
public abstract bool IsCollection { get; } |
||||
public abstract bool IsDictionary { get; } |
||||
public abstract IEnumerable<XamlType> AllowedTypes { get; } |
||||
public abstract IEnumerable<XamlType> AllowedKeyTypes { get; } |
||||
public abstract bool IsXData { get; } |
||||
public abstract bool IsNameScope { get; } |
||||
public abstract IEnumerable<Constructor> Constructors { get; } |
||||
public abstract XamlType ReturnValueType { get; } |
||||
public abstract bool HasTextSyntax { get; } |
||||
|
||||
public abstract string Namespace { get; } |
||||
public abstract XamlAssembly Assembly { get; } |
||||
public abstract XamlMember Member(string name); |
||||
public abstract IEnumerable<XamlType> ContentWrappers { get; } |
||||
public abstract Type SystemType { get; } |
||||
|
||||
public abstract bool IsAssignableFrom(XamlType type); |
||||
public abstract T GetAttribute<T>() where T : Attribute; |
||||
|
||||
public bool IsMarkupExtension |
||||
{ |
||||
get { return IntristicType.MarkupExtension.IsAssignableFrom(this); } |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return GetType().Name + ": " + Name; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,188 @@
@@ -0,0 +1,188 @@
|
||||
using System; |
||||
using System.Linq; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
using System.Reflection; |
||||
using System.Windows.Markup; |
||||
using System.Xml.Linq; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public class XamlTypeFinder |
||||
{ |
||||
public XamlTypeFinder(XamlProject project) |
||||
{ |
||||
Project = project; |
||||
} |
||||
|
||||
public XamlProject Project { get; private set; } |
||||
|
||||
Dictionary<XNamespace, XamlNamespace> xamlNamespaces = new Dictionary<XNamespace, XamlNamespace>(); |
||||
Dictionary<Mapping, XNamespace> xmlNamespaces = new Dictionary<Mapping, XNamespace>(); |
||||
|
||||
public XamlType FindType(XName name) |
||||
{ |
||||
if (name == IntristicType.CodeName) return IntristicType.Code; |
||||
if (name == IntristicType.XDataName) return IntristicType.XData; |
||||
|
||||
return FindType(name, null); |
||||
} |
||||
|
||||
public XamlType FindExtensionType(XName name) |
||||
{ |
||||
return FindType(name, "Extension"); |
||||
} |
||||
|
||||
XamlType FindType(XName name, string suffix) |
||||
{ |
||||
XamlNamespace ns; |
||||
if (!xamlNamespaces.TryGetValue(name.Namespace, out ns)) { |
||||
var mapping = ParseMappingString(name.Namespace); |
||||
if (mapping != null) { |
||||
ns = new XamlNamespace() { XmlNamespace = name.Namespace }; |
||||
AddMapping(ns, mapping); |
||||
xamlNamespaces[name.Namespace] = ns; |
||||
} |
||||
else { |
||||
return null; |
||||
} |
||||
} |
||||
foreach (var mapping in ns.Mappings) { |
||||
var type = mapping.Assembly.GetType(mapping.ClrNamespace + "." + name.LocalName + suffix); |
||||
if (type != null) return type; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public XNamespace GetXmlNamespaceForType(XamlType type) |
||||
{ |
||||
Mapping mapping = new Mapping() { Assembly = type.Assembly, ClrNamespace = type.Namespace }; |
||||
XNamespace ns; |
||||
if (xmlNamespaces.TryGetValue(mapping, out ns)) { |
||||
return ns; |
||||
} |
||||
if (mapping.Assembly == null || mapping.Assembly == Project.ProjectAssembly) { |
||||
return "clr-namespace:" + mapping.ClrNamespace; |
||||
} |
||||
return "clr-namespace:" + mapping.ClrNamespace + ";assembly=" + mapping.Assembly.Name; |
||||
} |
||||
|
||||
public void RegisterAssembly(XamlAssembly assembly) |
||||
{ |
||||
foreach (var def in assembly.XmlnsDefinitions) { |
||||
XamlNamespace ns; |
||||
if (!xamlNamespaces.TryGetValue(def.XmlNamespace, out ns)) { |
||||
ns = new XamlNamespace() { XmlNamespace = def.XmlNamespace }; |
||||
xamlNamespaces[ns.XmlNamespace] = ns; |
||||
} |
||||
//TODO def.AssemblyName
|
||||
AddMapping(ns, new Mapping() { Assembly = assembly, ClrNamespace = def.ClrNamespace }); |
||||
} |
||||
} |
||||
|
||||
public void UnregisterAssembly(XamlAssembly assembly) |
||||
{ |
||||
foreach (var ns in xamlNamespaces.Values) { |
||||
foreach (var mapping in ns.Mappings.ToArray()) { |
||||
if (mapping.Assembly == assembly) { |
||||
RemoveMapping(ns, mapping); |
||||
} |
||||
} |
||||
if (ns.Mappings.Count == 0) { |
||||
xamlNamespaces.Remove(ns.XmlNamespace); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void AddMapping(XamlNamespace ns, Mapping mapping) |
||||
{ |
||||
ns.Mappings.Add(mapping); |
||||
|
||||
// XamlWriter compares prefixes lengths (av < wpf, av < xps)
|
||||
// but we want Presentation2007Namespace as default
|
||||
XNamespace xmlns; |
||||
xmlNamespaces.TryGetValue(mapping, out xmlns); |
||||
if (xmlns != XamlConstants.Presentation2007Namespace) { |
||||
xmlNamespaces[mapping] = ns.XmlNamespace; |
||||
} |
||||
} |
||||
|
||||
void RemoveMapping(XamlNamespace ns, Mapping mapping) |
||||
{ |
||||
ns.Mappings.Remove(mapping); |
||||
xmlNamespaces.Remove(mapping); |
||||
} |
||||
|
||||
Mapping ParseMappingString(XNamespace ns) |
||||
{ |
||||
var text = ns.NamespaceName; |
||||
if (text.StartsWith("clr-namespace:")) { |
||||
var mapping = new Mapping(); |
||||
text = text.Substring("clr-namespace:".Length); |
||||
|
||||
int pos = text.IndexOf(';'); |
||||
if (pos < 0) { |
||||
mapping.ClrNamespace = text; |
||||
mapping.Assembly = FindAssembly(null); |
||||
} |
||||
else { |
||||
mapping.ClrNamespace = text.Substring(0, pos); |
||||
text = text.Substring(pos + 1).Trim(); |
||||
if (!text.StartsWith("assembly=")) { |
||||
throw new XamlException("Expected: 'assembly='"); |
||||
} |
||||
var assemblyName = text.Substring("assembly=".Length); |
||||
mapping.Assembly = FindAssembly(assemblyName); |
||||
} |
||||
return mapping; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
XamlAssembly FindAssembly(string name) |
||||
{ |
||||
XamlAssembly result = null; |
||||
if (string.IsNullOrEmpty(name)) { |
||||
result = Project.ProjectAssembly; |
||||
} |
||||
else { |
||||
foreach (var a in Project.References) { |
||||
if (a.Name == name) { |
||||
result = a; |
||||
} |
||||
} |
||||
} |
||||
if (result != null) { |
||||
return result; |
||||
} |
||||
throw new XamlException(string.Format("Assembly '{0}' not found in project.", name)); |
||||
} |
||||
|
||||
class XamlNamespace |
||||
{ |
||||
public XNamespace XmlNamespace; |
||||
public List<Mapping> Mappings = new List<Mapping>(); |
||||
} |
||||
|
||||
class Mapping : IEquatable<Mapping> |
||||
{ |
||||
public XamlAssembly Assembly; |
||||
public string ClrNamespace; |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return Assembly.GetHashCode() ^ ClrNamespace.GetHashCode(); |
||||
} |
||||
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
return Equals(obj as Mapping); |
||||
} |
||||
|
||||
public bool Equals(Mapping other) |
||||
{ |
||||
return other != null && other.Assembly == this.Assembly && other.ClrNamespace == this.ClrNamespace; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Xml.Linq; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
public abstract class XamlValue : XamlNode |
||||
{ |
||||
public object Instance; |
||||
|
||||
public MemberNode ParentMember |
||||
{ |
||||
get { return ParentNode as MemberNode; } |
||||
} |
||||
|
||||
public ObjectNode ParentObject |
||||
{ |
||||
get { return ParentMember != null ? ParentMember.ParentObject : null; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,448 @@
@@ -0,0 +1,448 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Diagnostics; |
||||
using System.Xml.Linq; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
class XmlTracker : Tracker |
||||
{ |
||||
public override void Process(DocumentChangedEventArgs e) |
||||
{ |
||||
if (e.OldNode != null) { |
||||
if (!TryUpdateMarkupExtension(e.OldParent)) { |
||||
Detach(e.OldNode, e.OldParent); |
||||
} |
||||
RemoveEmptyBranch(e.OldParent); |
||||
} |
||||
if (e.NewNode != null) { |
||||
if (!TryUpdateMarkupExtension(e.OldParent)) { |
||||
Attach(e.NewNode); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void Attach(XamlNode node) |
||||
{ |
||||
var value = node as XamlValue; |
||||
if (value == null) return; |
||||
if (!node.InDocument) return; |
||||
|
||||
var objectNode = node as ObjectNode; |
||||
if (objectNode != null && objectNode.IsDocumentRoot) { |
||||
var doc = objectNode.Document; |
||||
if (doc.XmlDocument == null) { |
||||
doc.XmlDocument = new XDocument(); |
||||
} |
||||
PrintObject(objectNode, doc.XmlDocument, null, null); |
||||
return; |
||||
} |
||||
|
||||
if (!TryAttachUsingSiblings(value)) { |
||||
AttachUsingPrint(value); |
||||
} |
||||
} |
||||
|
||||
static void Detach(XamlNode node, XamlNode nodeParent) |
||||
{ |
||||
if (node.XmlObject != null) { |
||||
RemoveXmlObject(node); |
||||
} |
||||
else { |
||||
if (nodeParent.InDocument) { |
||||
var currentXmlElement = nodeParent.FindAncestor(n => n.XmlObject != null).XmlObject as XElement; |
||||
if (currentXmlElement != null) { |
||||
currentXmlElement.RemoveNodes(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
static bool TryAttachUsingSiblings(XamlValue value) |
||||
{ |
||||
var values = value.ParentMember.Values; |
||||
if (values.Count > 1) { |
||||
var index = values.IndexOf(value); |
||||
if (index + 1 < values.Count) { |
||||
var before = values[index + 1].XmlObject as XNode; |
||||
PrintValue(value, null, null, before); |
||||
} |
||||
else { |
||||
var after = values[index - 1].XmlObject as XNode; |
||||
PrintValue(value, null, after, null); |
||||
} |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static void AttachUsingPrint(XamlValue value) |
||||
{ |
||||
var memberNode = value.FindAncestor(n => n is MemberNode && |
||||
(n as MemberNode).ParentObject.XmlObject != null) as MemberNode; |
||||
// TODO: XamlNode.IsAttached
|
||||
if (memberNode != null) { |
||||
PrintMember(memberNode, memberNode.ParentObject.XmlObject as XElement, null, null); |
||||
} |
||||
} |
||||
|
||||
static void RemoveEmptyBranch(XamlNode part) |
||||
{ |
||||
XamlNode prev = null; |
||||
while (IsEmpty(part)) { |
||||
prev = part; |
||||
part = part.ParentNode; |
||||
} |
||||
if (prev != null) { |
||||
prev.Remove(); |
||||
} |
||||
} |
||||
|
||||
static bool IsEmpty(XamlNode node) |
||||
{ |
||||
var objectNode = node as ObjectNode; |
||||
if (objectNode != null) { |
||||
if (objectNode.MemberNodes.Count == 0 && objectNode.IsRetrieved) { |
||||
return true; |
||||
} |
||||
} |
||||
else { |
||||
var memberNode = node as MemberNode; |
||||
if (memberNode != null) { |
||||
if (memberNode.Values.Count == 0) { |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static XName CreateMemberName(MemberNode node, bool forAttribute) |
||||
{ |
||||
if (node.Member.IsDirective) { |
||||
return Directive.GetDirectiveName(node.Member); |
||||
} |
||||
var type = node.Member.OwnerType; |
||||
if (type.IsAssignableFrom(node.ParentObject.Type)) { |
||||
if (forAttribute) { |
||||
return node.Member.Name; |
||||
} |
||||
type = node.ParentObject.Type; |
||||
} |
||||
var dottedName = type.Name + "." + node.Member.Name; |
||||
var typeNamespace = node.Document.Project.TypeFinder.GetXmlNamespaceForType(type); |
||||
if (forAttribute) { |
||||
var xmlElement = node.FindAncestor(n => n.XmlObject is XElement).XmlObject as XElement; |
||||
if (typeNamespace == xmlElement.Name.Namespace) { |
||||
return dottedName; |
||||
} |
||||
} |
||||
return typeNamespace + dottedName; |
||||
} |
||||
|
||||
static XName CreateTypeName(ObjectNode node) |
||||
{ |
||||
var typeNamespace = node.Document.Project.TypeFinder.GetXmlNamespaceForType(node.Type); |
||||
var typeName = node.Type.Name; |
||||
if (node.Type.IsMarkupExtension && typeName.EndsWith("Extension")) { |
||||
typeName = typeName.Substring(0, typeName.Length - "Extension".Length); |
||||
} |
||||
return typeNamespace + typeName; |
||||
} |
||||
|
||||
static bool TryPrintMarkupExtension(ObjectNode node, out string text) |
||||
{ |
||||
text = null; |
||||
if (!node.Type.IsMarkupExtension) { |
||||
return false; |
||||
} |
||||
|
||||
StringBuilder sb = new StringBuilder(); |
||||
sb.Append("{"); |
||||
|
||||
var typeName = CreateTypeName(node); |
||||
//TODO
|
||||
//var typePrefix = GetPrefixOfNamespace(node, typeName.Namespace);
|
||||
//sb.Append(typePrefix + ":" + typeName.LocalName);
|
||||
sb.Append(typeName.LocalName); |
||||
|
||||
List<XamlValue> positionalValues = new List<XamlValue>(); |
||||
var ctorArgs = node.FindMemberNode(IntristicMember.ConsructorArgs); |
||||
|
||||
if (ctorArgs != null) { |
||||
positionalValues.AddRange(ctorArgs.Values); |
||||
} |
||||
else { |
||||
var ctor = node.Type.Constructors.FirstOrDefault(); |
||||
if (ctor != null && ctor.CorrespondingMembers != null) { |
||||
foreach (var ctorMember in ctor.CorrespondingMembers) { |
||||
var ctorMemberNode = node.FindMemberNode(ctorMember); |
||||
if (ctorMemberNode == null || ctorMemberNode.SingleValue == null) { |
||||
positionalValues.Clear(); |
||||
break; |
||||
} |
||||
positionalValues.Add(ctorMemberNode.SingleValue); |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool first = true; |
||||
HashSet<MemberNode> printed = new HashSet<MemberNode>(); |
||||
|
||||
if (positionalValues.Count > 0) { |
||||
foreach (var value in positionalValues) { |
||||
if (first) { |
||||
sb.Append(" "); |
||||
first = false; |
||||
} |
||||
else { |
||||
sb.Append(", "); |
||||
} |
||||
|
||||
string valueText; |
||||
if (!TryPrintMarkupExtensionValue(value, out valueText)) { |
||||
return false; |
||||
} |
||||
sb.Append(valueText); |
||||
|
||||
printed.Add(value.ParentMember); |
||||
} |
||||
} |
||||
|
||||
foreach (var memberNode in node.MemberNodes) { |
||||
if (printed.Contains(memberNode)) { |
||||
continue; |
||||
} |
||||
|
||||
if (first) { |
||||
sb.Append(" "); |
||||
first = false; |
||||
} |
||||
else { |
||||
sb.Append(", "); |
||||
} |
||||
|
||||
var memberName = CreateMemberName(memberNode, true); |
||||
sb.Append(memberName.LocalName); |
||||
|
||||
sb.Append("="); |
||||
|
||||
string valueText; |
||||
if (!TryPrintMarkupExtensionValue(memberNode.SingleValue, out valueText)) { |
||||
return false; |
||||
} |
||||
sb.Append(valueText); |
||||
} |
||||
|
||||
sb.Append("}"); |
||||
text = sb.ToString(); |
||||
return true; |
||||
} |
||||
|
||||
static bool TryPrintMarkupExtensionValue(XamlValue value, out string text) |
||||
{ |
||||
text = null; |
||||
if (value is TextNode) { |
||||
text = (value as TextNode).Text; |
||||
} |
||||
else if (value is ObjectNode) { |
||||
if (!TryPrintMarkupExtension(value as ObjectNode, out text)) { |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
static XNamespace GetPrefixOfNamespace(XamlNode node, XNamespace ns) |
||||
{ |
||||
var xmlElement = node.FindAncestor(n => n.XmlObject is XElement).XmlObject as XElement; |
||||
return xmlElement.GetPrefixOfNamespace(ns); |
||||
} |
||||
|
||||
static bool TryUpdateMarkupExtension(XamlNode node) |
||||
{ |
||||
MemberNode root = null; |
||||
while (node != null) { |
||||
MemberNode memberNode = node as MemberNode; |
||||
if (memberNode != null) { |
||||
var markupExtensionNode = memberNode.SingleValue as ObjectNode; |
||||
if (markupExtensionNode != null && markupExtensionNode.Type.IsMarkupExtension) { |
||||
root = memberNode; |
||||
} |
||||
} |
||||
node = node.ParentNode; |
||||
} |
||||
|
||||
if (root != null) { |
||||
string text; |
||||
if (TryPrintMarkupExtension(root.SingleValue as ObjectNode, out text)) { |
||||
EnsureXmlAttribute(root, root.ParentObject.XmlObject as XElement).Value = text; |
||||
foreach (var descendant in root.Descendants()) { |
||||
descendant.XmlObject = null; |
||||
} |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
static void PrintObject(ObjectNode node, XContainer currentXmlContainer, XNode after, XNode before) |
||||
{ |
||||
if (node.IsRetrieved) { |
||||
foreach (var memberNode in node.MemberNodes) { |
||||
PrintMember(memberNode, currentXmlContainer as XElement, after, before); |
||||
} |
||||
} |
||||
else { |
||||
if (node.XmlObject == null) { |
||||
var typeFinder = node.Document.Project.TypeFinder; |
||||
var xmlElement = new XElement(typeFinder.GetXmlNamespaceForType(node.Type) + node.Type.Name); |
||||
node.XmlObject = xmlElement; |
||||
|
||||
// preserve usual namespaces
|
||||
if (node.IsDocumentRoot) { |
||||
xmlElement.Add(new XAttribute("xmlns", xmlElement.Name.Namespace)); |
||||
xmlElement.Add(new XAttribute(XNamespace.Xmlns + "x", XamlConstants.XamlNamespace)); |
||||
} |
||||
|
||||
AddXmlObject(node, currentXmlContainer, after, before); |
||||
|
||||
foreach (var memberNode in node.MemberNodes) { |
||||
PrintMember(memberNode, xmlElement, after, before); |
||||
} |
||||
} |
||||
else { |
||||
AddXmlObject(node, currentXmlContainer, after, before); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void PrintMember(MemberNode node, XElement currentXmlElement, XNode after, XNode before) |
||||
{ |
||||
if (node.SingleValue is TextNode && node.Member != IntristicMember.Items) { |
||||
if (node.Member == IntristicMember.InitializationText) { |
||||
PrintValue(node.SingleValue, currentXmlElement, after, before); |
||||
} |
||||
else { |
||||
EnsureXmlAttribute(node, currentXmlElement).Value = (node.SingleValue as TextNode).Text; |
||||
} |
||||
} |
||||
else { |
||||
var me = node.SingleValue as ObjectNode; |
||||
if (me != null && me.Type.IsMarkupExtension) { |
||||
string text; |
||||
if (TryPrintMarkupExtension(me, out text)) { |
||||
EnsureXmlAttribute(node, currentXmlElement).Value = text; |
||||
return; |
||||
} |
||||
} |
||||
var xmlElement = EnsureXmlElement(node, currentXmlElement); |
||||
foreach (var value in node.Values) { |
||||
PrintValue(value, xmlElement, after, before); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void PrintValue(XamlValue value, XElement currentXmlElement, XNode after, XNode before) |
||||
{ |
||||
var textNode = value as TextNode; |
||||
if (textNode != null) { |
||||
var text = textNode.Text; |
||||
textNode.XmlObject = new XText(text); |
||||
AddXmlObject(textNode, currentXmlElement, after, before); |
||||
|
||||
if (text.StartsWith(" ") || text.EndsWith(" ")) { |
||||
var xmlElement = currentXmlElement ?? (after != null ? after.Parent : null) ?? before.Parent; |
||||
xmlElement.SetAttributeValue(XamlConstants.XmlSpaceName, "preserve"); |
||||
} |
||||
} |
||||
else { |
||||
PrintObject(value as ObjectNode, currentXmlElement, after, before); |
||||
} |
||||
} |
||||
|
||||
static void AddXmlObject(XamlNode node, XContainer currentXmlContainer, XNode after, XNode before) |
||||
{ |
||||
if (after != null) { |
||||
after.AddAfterSelf(node.XmlObject); |
||||
} |
||||
else if (before != null) { |
||||
before.AddBeforeSelf(node.XmlObject); |
||||
} |
||||
else if (node.XmlObject.Document == null) { |
||||
currentXmlContainer.Add(node.XmlObject); |
||||
} |
||||
} |
||||
|
||||
static void RemoveXmlObject(XamlNode node) |
||||
{ |
||||
if (node.XmlObject is XAttribute) { |
||||
(node.XmlObject as XAttribute).Remove(); |
||||
node.XmlObject = null; |
||||
} |
||||
else if (node.XmlObject is XNode) { |
||||
(node.XmlObject as XNode).Remove(); |
||||
} |
||||
//node.XmlObject = null;
|
||||
} |
||||
|
||||
static XAttribute EnsureXmlAttribute(MemberNode node, XElement currentXmlElement) |
||||
{ |
||||
var xmlAttribute = node.XmlObject as XAttribute; |
||||
if (xmlAttribute == null) { |
||||
if (node.XmlObject != null) { |
||||
RemoveXmlObject(node); |
||||
} |
||||
else if (IsContent(node)) { |
||||
currentXmlElement.RemoveNodes(); |
||||
} |
||||
|
||||
xmlAttribute = new XAttribute(CreateMemberName(node, true), ""); |
||||
currentXmlElement.Add(xmlAttribute); |
||||
node.XmlObject = xmlAttribute; |
||||
} |
||||
return xmlAttribute; |
||||
} |
||||
|
||||
static XElement EnsureXmlElement(MemberNode node, XElement currentXmlElement) |
||||
{ |
||||
var xmlElement = node.XmlObject as XElement; |
||||
if (xmlElement == null) { |
||||
if (node.XmlObject != null) { |
||||
RemoveXmlObject(node); |
||||
} |
||||
if (IsContent(node)) { |
||||
return currentXmlElement; |
||||
} |
||||
|
||||
xmlElement = new XElement(CreateMemberName(node, false)); |
||||
currentXmlElement.AddFirst(xmlElement); |
||||
node.XmlObject = xmlElement; |
||||
} |
||||
return xmlElement; |
||||
} |
||||
|
||||
static bool IsContent(MemberNode node) |
||||
{ |
||||
return |
||||
node.Member == node.ParentObject.Type.ContentProperty || |
||||
node.Member == IntristicMember.Items || |
||||
node.Member == IntristicMember.InitializationText; |
||||
} |
||||
|
||||
public static XElement GetNamespaceProvider(ObjectNode node) |
||||
{ |
||||
var nodeWithXmlElement = node.FindAncestor(n => n.XmlObject is XElement); |
||||
if (nodeWithXmlElement != null) { |
||||
return (nodeWithXmlElement.XmlObject as XElement); |
||||
} |
||||
if (node.Document.XmlDocument != null && node.Document.XmlDocument.Root != null) { |
||||
return node.Document.XmlDocument.Root; |
||||
} |
||||
return new XElement("Empty"); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.Xaml |
||||
{ |
||||
class XmlnsDefinition |
||||
{ |
||||
} |
||||
} |
@ -0,0 +1,75 @@
@@ -0,0 +1,75 @@
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<ProjectGuid>{F390DA70-1FE1-4715-81A0-389AB010C130}</ProjectGuid> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>ICSharpCode.XamlBinding.Tests</RootNamespace> |
||||
<AssemblyName>ICSharpCode.XamlBinding.Tests</AssemblyName> |
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> |
||||
<AppDesignerFolder>Properties</AppDesignerFolder> |
||||
<SourceAnalysisOverrideSettingsFile>C:\Users\Daniel\AppData\Roaming\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile> |
||||
<OutputPath>..\..\..\..\..\bin\UnitTests\</OutputPath> |
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
||||
<NoStdLib>False</NoStdLib> |
||||
<WarningLevel>4</WarningLevel> |
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>Full</DebugType> |
||||
<Optimize>False</Optimize> |
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
||||
<DebugSymbols>False</DebugSymbols> |
||||
<DebugType>None</DebugType> |
||||
<Optimize>True</Optimize> |
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> |
||||
<RegisterForComInterop>False</RegisterForComInterop> |
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> |
||||
<BaseAddress>4194304</BaseAddress> |
||||
<PlatformTarget>AnyCPU</PlatformTarget> |
||||
<FileAlignment>4096</FileAlignment> |
||||
</PropertyGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
||||
<ItemGroup> |
||||
<Reference Include="nunit.framework"> |
||||
<HintPath>..\..\..\..\Tools\NUnit\nunit.framework.dll</HintPath> |
||||
<Private>False</Private> |
||||
</Reference> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Core"> |
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System.Xml" /> |
||||
<Reference Include="System.Xml.Linq"> |
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||
</Reference> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="..\..\..\..\Main\GlobalAssemblyInfo.cs"> |
||||
<Link>Properties\GlobalAssemblyInfo.cs</Link> |
||||
</Compile> |
||||
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||
<Compile Include="XamlExpressionFinderTests.cs" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ProjectReference Include="..\..\..\..\Main\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj"> |
||||
<Project>{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}</Project> |
||||
<Name>ICSharpCode.SharpDevelop.Dom</Name> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\DisplayBindings\XmlEditor\Project\XmlEditor.csproj"> |
||||
<Project>{6B717BD1-CD5E-498C-A42E-9E6A4584DC48}</Project> |
||||
<Name>XmlEditor</Name> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\XamlBinding\XamlBinding.csproj"> |
||||
<Project>{7C96B65D-28A5-4F28-A35B-8D83CE831EE8}</Project> |
||||
<Name>XamlBinding</Name> |
||||
</ProjectReference> |
||||
</ItemGroup> |
||||
</Project> |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3494 $</version>
|
||||
// </file>
|
||||
|
||||
|
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using System; |
||||
using NUnit.Framework; |
||||
using NUnit.Framework.SyntaxHelpers; |
||||
|
||||
namespace ICSharpCode.XamlBinding.Tests |
||||
{ |
||||
[TestFixture] |
||||
public class XamlExpressionFinderTests |
||||
{ |
||||
XamlExpressionContext GetXamlContext(string text) |
||||
{ |
||||
return (XamlExpressionContext)GetContext(text); |
||||
} |
||||
|
||||
ExpressionContext GetContext(string text) |
||||
{ |
||||
return XamlExpressionFinder.Instance.FindExpression(text, text.Length).Context; |
||||
} |
||||
|
||||
[Test] |
||||
public void FindContextAfterElementName() |
||||
{ |
||||
XamlExpressionContext c = GetXamlContext("<Window><Grid"); |
||||
Assert.AreEqual(2, c.ElementPath.Elements.Count); |
||||
Assert.AreEqual("Window > Grid", c.ElementPath.ToString()); |
||||
Assert.IsNull(c.AttributeName); |
||||
Assert.IsFalse(c.InAttributeValue); |
||||
} |
||||
|
||||
[Test] |
||||
public void FindContextAtElementStart() |
||||
{ |
||||
XamlExpressionContext c = GetXamlContext("<Window><"); |
||||
Assert.AreEqual(0, c.ElementPath.Elements.Count); |
||||
Assert.IsNull(c.AttributeName); |
||||
Assert.IsFalse(c.InAttributeValue); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
<AddIn name = "XAML binding" |
||||
author = "Daniel Grunwald" |
||||
copyright = "prj:///doc/copyright.txt" |
||||
url = "http://icsharpcode.net" |
||||
description = "Enables code-completion for xaml files."> |
||||
|
||||
<!-- |
||||
This file is unrelated to the WPF Designer, it is a language binding for .xaml files. |
||||
It allows using Go to definition, find references, code completion in .xaml files. |
||||
--> |
||||
|
||||
<Manifest> |
||||
<Identity name = "ICSharpCode.XamlBinding"/> |
||||
<Dependency addin = "ICSharpCode.XmlEditor" requirePreload = "true"/> |
||||
</Manifest> |
||||
|
||||
<Runtime> |
||||
<Import assembly = "ICSharpCode.XamlBinding.dll"/> |
||||
</Runtime> |
||||
|
||||
<Path name = "/Workspace/Icons"> |
||||
<Icon id = "XamlFileIcon" |
||||
extensions = ".xaml" |
||||
resource = "FileIcons.XmlIcon" /> |
||||
</Path> |
||||
|
||||
<Path name = "/SharpDevelop/Workbench/FileFilter"> |
||||
<FileFilter id = "Xaml" |
||||
insertbefore="AllFiles" |
||||
name = "Xaml files (*.xaml)" |
||||
extensions = "*.xaml"/> |
||||
</Path> |
||||
|
||||
<Path name = "/Workspace/Parser"> |
||||
<Parser id = "XAML" |
||||
supportedextensions = ".xaml" |
||||
class = "ICSharpCode.XamlBinding.XamlParser"/> |
||||
</Path> |
||||
|
||||
<Path name = "/AddIns/DefaultTextEditor/CodeCompletion"> |
||||
<CodeCompletionBinding id = "Xaml" extensions = ".xaml" class = "ICSharpCode.XamlBinding.XamlCodeCompletionBinding"/> |
||||
</Path> |
||||
</AddIn> |
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> |
||||
<PropertyGroup> |
||||
<ProjectGuid>{7C96B65D-28A5-4F28-A35B-8D83CE831EE8}</ProjectGuid> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>ICSharpCode.XamlBinding</RootNamespace> |
||||
<AssemblyName>ICSharpCode.XamlBinding</AssemblyName> |
||||
<OutputPath>..\..\..\..\..\AddIns\AddIns\BackendBindings\XamlBinding</OutputPath> |
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
||||
<NoStdLib>False</NoStdLib> |
||||
<WarningLevel>4</WarningLevel> |
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> |
||||
<SourceAnalysisOverrideSettingsFile>C:\Users\Daniel\AppData\Roaming\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile> |
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>Full</DebugType> |
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
<Optimize>False</Optimize> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
||||
<DebugSymbols>False</DebugSymbols> |
||||
<DebugType>None</DebugType> |
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> |
||||
<RegisterForComInterop>False</RegisterForComInterop> |
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> |
||||
<BaseAddress>4194304</BaseAddress> |
||||
<PlatformTarget>AnyCPU</PlatformTarget> |
||||
<FileAlignment>4096</FileAlignment> |
||||
</PropertyGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
||||
<ItemGroup> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Core"> |
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System.Data" /> |
||||
<Reference Include="System.Windows.Forms" /> |
||||
<Reference Include="System.Xml" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<None Include="XamlBinding.addin"> |
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||
</None> |
||||
<Compile Include="..\..\..\..\Main\GlobalAssemblyInfo.cs"> |
||||
<Link>Properties\GlobalAssemblyInfo.cs</Link> |
||||
</Compile> |
||||
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||
<Compile Include="XamlClassReturnType.cs" /> |
||||
<Compile Include="XamlCodeCompletionBinding.cs" /> |
||||
<Compile Include="XamlCompilationUnit.cs" /> |
||||
<Compile Include="XamlExpressionContext.cs" /> |
||||
<Compile Include="XamlExpressionFinder.cs" /> |
||||
<Compile Include="XamlParser.cs" /> |
||||
<Compile Include="XamlResolver.cs" /> |
||||
<ProjectReference Include="..\..\..\..\Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj"> |
||||
<Project>{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}</Project> |
||||
<Name>ICSharpCode.TextEditor</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\..\Libraries\NRefactory\Project\NRefactory.csproj"> |
||||
<Project>{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}</Project> |
||||
<Name>NRefactory</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj"> |
||||
<Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project> |
||||
<Name>ICSharpCode.SharpDevelop</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\..\Main\Core\Project\ICSharpCode.Core.csproj"> |
||||
<Project>{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}</Project> |
||||
<Name>ICSharpCode.Core</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\..\Main\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj"> |
||||
<Project>{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}</Project> |
||||
<Name>ICSharpCode.SharpDevelop.Dom</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\DisplayBindings\XmlEditor\Project\XmlEditor.csproj"> |
||||
<Project>{6B717BD1-CD5E-498C-A42E-9E6A4584DC48}</Project> |
||||
<Name>XmlEditor</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
</ItemGroup> |
||||
<!--<Target Name="AfterBuild"> |
||||
<Copy SourceFiles="@(CopyFile)" DestinationFolder="$(OutputPath)" /> |
||||
</Target>--> |
||||
</Project> |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 2569 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
|
||||
namespace ICSharpCode.XamlBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Description of XamlClassReturnType.
|
||||
/// </summary>
|
||||
public class XamlClassReturnType : ProxyReturnType |
||||
{ |
||||
XamlCompilationUnit compilationUnit; |
||||
string xmlNamespace; |
||||
string className; |
||||
|
||||
public XamlClassReturnType(XamlCompilationUnit compilationUnit, string xmlNamespace, string className) |
||||
{ |
||||
if (compilationUnit == null) |
||||
throw new ArgumentNullException("compilationUnit"); |
||||
|
||||
this.compilationUnit = compilationUnit; |
||||
this.xmlNamespace = xmlNamespace; |
||||
this.className = className ?? ""; |
||||
} |
||||
|
||||
public override IReturnType BaseType |
||||
{ |
||||
get |
||||
{ |
||||
return compilationUnit.FindType(xmlNamespace, className); |
||||
} |
||||
} |
||||
|
||||
public override string Name |
||||
{ |
||||
get { return className; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,102 @@
@@ -0,0 +1,102 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3494 $</version>
|
||||
// </file>
|
||||
|
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using System; |
||||
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.TextEditor.Gui.CompletionWindow; |
||||
using ICSharpCode.XmlEditor; |
||||
|
||||
namespace ICSharpCode.XamlBinding |
||||
{ |
||||
public class XamlCodeCompletionBinding : ICodeCompletionBinding |
||||
{ |
||||
public bool HandleKeyPress(SharpDevelopTextAreaControl editor, char ch) |
||||
{ |
||||
if (ch == '<') { |
||||
editor.ShowCompletionWindow(new XamlCompletionDataProvider(XamlExpressionContext.Empty), ch); |
||||
return true; |
||||
} |
||||
else if (char.IsLetter(ch)) { |
||||
int offset = editor.ActiveTextAreaControl.TextArea.Caret.Offset; |
||||
if (offset > 0) { |
||||
char c = editor.Document.GetCharAt(offset - 1); |
||||
if (c == ' ' || c == '\t') { |
||||
XmlElementPath path = XmlParser.GetActiveElementStartPathAtIndex(editor.Text, offset); |
||||
if (path != null && path.Elements.Count > 0) { |
||||
editor.ShowCompletionWindow( |
||||
new XamlCompletionDataProvider( |
||||
new XamlExpressionContext(path, "", false) |
||||
) { IsAttributeCompletion = true } |
||||
, '\0'); |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public bool CtrlSpace(SharpDevelopTextAreaControl editor) |
||||
{ |
||||
XamlCompletionDataProvider provider = new XamlCompletionDataProvider(); |
||||
provider.AllowCompleteExistingExpression = true; |
||||
editor.ShowCompletionWindow(provider, '\0'); |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
sealed class XamlCompletionDataProvider : CtrlSpaceCompletionDataProvider |
||||
{ |
||||
public XamlCompletionDataProvider() |
||||
{ |
||||
} |
||||
|
||||
public XamlCompletionDataProvider(ExpressionContext overrideContext) |
||||
: base(overrideContext) |
||||
{ |
||||
} |
||||
|
||||
public override CompletionDataProviderKeyResult ProcessKey(char key) |
||||
{ |
||||
if (key == ':' || key == '.') { |
||||
return CompletionDataProviderKeyResult.NormalKey; |
||||
} |
||||
else { |
||||
return base.ProcessKey(key); |
||||
} |
||||
} |
||||
|
||||
public bool IsAttributeCompletion; |
||||
|
||||
public override bool InsertAction(ICompletionData data, ICSharpCode.TextEditor.TextArea textArea, int insertionOffset, char key) |
||||
{ |
||||
CodeCompletionData ccData = data as CodeCompletionData; |
||||
if (IsAttributeCompletion && ccData != null) { |
||||
textArea.Caret.Position = textArea.Document.OffsetToPosition(insertionOffset); |
||||
textArea.InsertString(ccData.Text + "=\"\""); |
||||
textArea.Caret.Column -= 1; |
||||
|
||||
SharpDevelopTextAreaControl editor = textArea.MotherTextEditorControl as SharpDevelopTextAreaControl; |
||||
if (editor != null) { |
||||
WorkbenchSingleton.SafeThreadAsyncCall( |
||||
delegate { |
||||
XamlCompletionDataProvider provider = new XamlCompletionDataProvider(); |
||||
provider.AllowCompleteExistingExpression = true; |
||||
editor.ShowCompletionWindow(provider, '\0'); |
||||
} |
||||
); |
||||
} |
||||
return false; |
||||
} |
||||
else { |
||||
return base.InsertAction(data, textArea, insertionOffset, key); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,128 @@
@@ -0,0 +1,128 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3494 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.XamlBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Description of XamlCompilationUnit.
|
||||
/// </summary>
|
||||
public class XamlCompilationUnit : DefaultCompilationUnit |
||||
{ |
||||
public XamlCompilationUnit(IProjectContent projectContent) |
||||
: base(projectContent) |
||||
{ |
||||
} |
||||
|
||||
public IReturnType CreateType(string xmlNamespace, string className) |
||||
{ |
||||
if (xmlNamespace.StartsWith("clr-namespace:")) { |
||||
return CreateClrNamespaceType(this.ProjectContent, xmlNamespace, className); |
||||
} |
||||
else { |
||||
return new XamlClassReturnType(this, xmlNamespace, className); |
||||
} |
||||
} |
||||
|
||||
static IReturnType CreateClrNamespaceType(IProjectContent pc, string xmlNamespace, string className) |
||||
{ |
||||
string namespaceName = GetNamespaceNameFromClrNamespace(xmlNamespace); |
||||
return new GetClassReturnType(pc, namespaceName + "." + className, 0); |
||||
} |
||||
|
||||
static string GetNamespaceNameFromClrNamespace(string xmlNamespace) |
||||
{ |
||||
string namespaceName = xmlNamespace.Substring("clr-namespace:".Length); |
||||
int pos = namespaceName.IndexOf(';'); |
||||
if (pos >= 0) { |
||||
// we expect that the target type is also a reference of the project, so we
|
||||
// can ignore the assembly part after the ;
|
||||
namespaceName = namespaceName.Substring(0, pos); |
||||
} |
||||
return namespaceName; |
||||
} |
||||
|
||||
public IReturnType FindType(string xmlNamespace, string className) |
||||
{ |
||||
return FindType(this.ProjectContent, xmlNamespace, className); |
||||
} |
||||
|
||||
public static IReturnType FindType(IProjectContent pc, string xmlNamespace, string className) |
||||
{ |
||||
if (pc == null) |
||||
throw new ArgumentNullException("pc"); |
||||
if (xmlNamespace == null || className == null) |
||||
return null; |
||||
if (xmlNamespace.StartsWith("clr-namespace:")) { |
||||
return CreateClrNamespaceType(pc, xmlNamespace, className); |
||||
} |
||||
else { |
||||
IReturnType type = FindTypeInAssembly(pc, xmlNamespace, className); |
||||
if (type != null) |
||||
return type; |
||||
foreach (IProjectContent p in pc.ReferencedContents) { |
||||
type = FindTypeInAssembly(p, xmlNamespace, className); |
||||
if (type != null) |
||||
return type; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
static IReturnType FindTypeInAssembly(IProjectContent projectContent, string xmlNamespace, string className) |
||||
{ |
||||
foreach (IAttribute att in projectContent.GetAssemblyAttributes()) { |
||||
if (att.PositionalArguments.Count == 2 |
||||
&& att.AttributeType.FullyQualifiedName == "System.Windows.Markup.XmlnsDefinitionAttribute") { |
||||
string namespaceName = att.PositionalArguments[1] as string; |
||||
if (xmlNamespace.Equals(att.PositionalArguments[0]) && namespaceName != null) { |
||||
IClass c = projectContent.GetClass(namespaceName + "." + className, 0); |
||||
if (c != null) |
||||
return c.DefaultReturnType; |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static ArrayList GetNamespaceMembers(IProjectContent pc, string xmlNamespace) |
||||
{ |
||||
if (pc == null) |
||||
throw new ArgumentNullException("pc"); |
||||
if (xmlNamespace == null) |
||||
return null; |
||||
if (xmlNamespace.StartsWith("clr-namespace:")) { |
||||
return pc.GetNamespaceContents(GetNamespaceNameFromClrNamespace(xmlNamespace)); |
||||
} |
||||
else { |
||||
ArrayList list = new ArrayList(); |
||||
AddNamespaceMembersInAssembly(pc, xmlNamespace, list); |
||||
foreach (IProjectContent p in pc.ReferencedContents) { |
||||
AddNamespaceMembersInAssembly(p, xmlNamespace, list); |
||||
} |
||||
return list; |
||||
} |
||||
} |
||||
|
||||
static void AddNamespaceMembersInAssembly(IProjectContent projectContent, string xmlNamespace, ArrayList list) |
||||
{ |
||||
foreach (IAttribute att in projectContent.GetAssemblyAttributes()) { |
||||
if (att.PositionalArguments.Count == 2 |
||||
&& att.AttributeType.FullyQualifiedName == "System.Windows.Markup.XmlnsDefinitionAttribute") { |
||||
string namespaceName = att.PositionalArguments[1] as string; |
||||
if (xmlNamespace.Equals(att.PositionalArguments[0]) && namespaceName != null) { |
||||
projectContent.AddNamespaceContents(list, namespaceName, projectContent.Language, false); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3494 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Text; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.XmlEditor; |
||||
|
||||
namespace ICSharpCode.XamlBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Represents the context of a location in a XAML document.
|
||||
/// </summary>
|
||||
public sealed class XamlExpressionContext : ExpressionContext |
||||
{ |
||||
public static readonly XamlExpressionContext Empty = new XamlExpressionContext(new XmlElementPath(), null, false); |
||||
|
||||
public readonly XmlElementPath ElementPath; |
||||
public readonly string AttributeName; |
||||
public readonly bool InAttributeValue; |
||||
|
||||
public XamlExpressionContext(XmlElementPath elementPath, string attributeName, bool inAttributeValue) |
||||
{ |
||||
if (elementPath == null) |
||||
throw new ArgumentNullException("elementPath"); |
||||
this.ElementPath = elementPath; |
||||
this.AttributeName = attributeName; |
||||
this.InAttributeValue = inAttributeValue; |
||||
} |
||||
|
||||
public override bool ShowEntry(object o) |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
StringBuilder b = new StringBuilder(); |
||||
b.Append("[XamlExpressionContext "); |
||||
for (int i = 0; i < ElementPath.Elements.Count; i++) { |
||||
if (i > 0) b.Append(">"); |
||||
if (!string.IsNullOrEmpty(ElementPath.Elements[i].Prefix)) { |
||||
b.Append(ElementPath.Elements[i].Prefix); |
||||
b.Append(':'); |
||||
} |
||||
b.Append(ElementPath.Elements[i].Name); |
||||
} |
||||
if (AttributeName != null) { |
||||
b.Append(" AttributeName="); |
||||
b.Append(AttributeName); |
||||
if (InAttributeValue) { |
||||
b.Append(" InAttributeValue"); |
||||
} |
||||
} |
||||
b.Append("]"); |
||||
return b.ToString(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,75 @@
@@ -0,0 +1,75 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3494 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Text; |
||||
using System.Xml; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.XmlEditor; |
||||
|
||||
namespace ICSharpCode.XamlBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Description of XamlExpressionFinder.
|
||||
/// </summary>
|
||||
public class XamlExpressionFinder : IExpressionFinder |
||||
{ |
||||
public static readonly XamlExpressionFinder Instance = new XamlExpressionFinder(); |
||||
|
||||
bool IsValidChar(char c) |
||||
{ |
||||
return char.IsLetterOrDigit(c) || c == '_' || c == ':' || c == '.'; |
||||
} |
||||
|
||||
public ExpressionResult FindExpression(string text, int offset) |
||||
{ |
||||
int pos = offset - 1; |
||||
while (pos > 0 && IsValidChar(text[pos])) { |
||||
pos--; |
||||
} |
||||
pos++; |
||||
return new ExpressionResult(text.Substring(pos, offset - pos), GetContext(text, offset)); |
||||
} |
||||
|
||||
public ExpressionResult FindFullExpression(string text, int offset) |
||||
{ |
||||
int start = offset - 1; |
||||
while (start > 0 && IsValidChar(text[start])) { |
||||
start--; |
||||
} |
||||
start++; |
||||
while (offset < text.Length && IsValidChar(text[offset])) { |
||||
offset++; |
||||
} |
||||
return new ExpressionResult(text.Substring(start, offset - start), GetContext(text, offset)); |
||||
} |
||||
|
||||
public string RemoveLastPart(string expression) |
||||
{ |
||||
return ""; |
||||
} |
||||
|
||||
ExpressionContext GetContext(string text, int offset) |
||||
{ |
||||
XmlElementPath path = XmlParser.GetActiveElementStartPathAtIndex(text, offset); |
||||
if (path == null || path.Elements.Count == 0) { |
||||
if (offset > 0 && text[offset - 1] == '<') |
||||
return XamlExpressionContext.Empty; |
||||
else |
||||
return ExpressionContext.Default; |
||||
} |
||||
string attributeName = XmlParser.GetAttributeNameAtIndex(text, offset); |
||||
if (!string.IsNullOrEmpty(attributeName)) { |
||||
return new XamlExpressionContext(path, attributeName, XmlParser.IsInsideAttributeValue(text, offset)); |
||||
} |
||||
else { |
||||
return new XamlExpressionContext(path, null, false); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,151 @@
@@ -0,0 +1,151 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 2568 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.IO; |
||||
using System.Xml; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
|
||||
namespace ICSharpCode.XamlBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Parses xaml files to partial classes for the Dom.
|
||||
/// </summary>
|
||||
public class XamlParser : IParser |
||||
{ |
||||
string[] lexerTags; |
||||
|
||||
public string[] LexerTags |
||||
{ |
||||
get |
||||
{ |
||||
return lexerTags; |
||||
} |
||||
set |
||||
{ |
||||
lexerTags = value; |
||||
} |
||||
} |
||||
|
||||
public LanguageProperties Language |
||||
{ |
||||
get |
||||
{ |
||||
return LanguageProperties.CSharp; |
||||
} |
||||
} |
||||
|
||||
public bool CanParse(string fileName) |
||||
{ |
||||
return Path.GetExtension(fileName).Equals(".xaml", StringComparison.InvariantCultureIgnoreCase); |
||||
} |
||||
|
||||
public bool CanParse(ICSharpCode.SharpDevelop.Project.IProject project) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
const string XamlNamespace = "http://schemas.microsoft.com/winfx/2006/xaml"; |
||||
|
||||
public ICompilationUnit Parse(IProjectContent projectContent, string fileName, string fileContent) |
||||
{ |
||||
XamlCompilationUnit cu = new XamlCompilationUnit(projectContent); |
||||
cu.FileName = fileName; |
||||
try { |
||||
using (XmlTextReader r = new XmlTextReader(new StringReader(fileContent))) { |
||||
r.WhitespaceHandling = WhitespaceHandling.Significant; |
||||
r.Read(); |
||||
r.MoveToContent(); |
||||
DomRegion classStart = new DomRegion(r.LineNumber, r.LinePosition - 1); |
||||
string className = r.GetAttribute("Class", XamlNamespace); |
||||
if (string.IsNullOrEmpty(className)) { |
||||
LoggingService.Debug("XamlParser: returning empty cu because root element has no Class attribute"); |
||||
} |
||||
else { |
||||
DefaultClass c = new DefaultClass(cu, className); |
||||
c.Modifiers = ModifierEnum.Partial; |
||||
c.Region = classStart; |
||||
c.BaseTypes.Add(TypeFromXmlNode(cu, r)); |
||||
cu.Classes.Add(c); |
||||
|
||||
DefaultMethod initializeComponent = new DefaultMethod( |
||||
"InitializeComponent", |
||||
projectContent.SystemTypes.Void, |
||||
ModifierEnum.Public | ModifierEnum.Synthetic, |
||||
classStart, DomRegion.Empty, |
||||
c); |
||||
c.Methods.Add(initializeComponent); |
||||
|
||||
ParseXamlElement(cu, c, r); |
||||
if (r.NodeType == XmlNodeType.EndElement) { |
||||
c.Region = new DomRegion(classStart.BeginLine, classStart.BeginColumn, r.LineNumber, r.LinePosition + r.Name.Length); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
catch (XmlException ex) { |
||||
LoggingService.Debug("XamlParser exception: " + ex.ToString()); |
||||
cu.ErrorsDuringCompile = true; |
||||
} |
||||
return cu; |
||||
} |
||||
|
||||
IReturnType TypeFromXmlNode(XamlCompilationUnit cu, XmlReader r) |
||||
{ |
||||
return cu.CreateType(r.NamespaceURI, r.LocalName); |
||||
} |
||||
|
||||
void ParseXamlElement(XamlCompilationUnit cu, DefaultClass c, XmlTextReader r) |
||||
{ |
||||
Debug.Assert(r.NodeType == XmlNodeType.Element); |
||||
string name = r.GetAttribute("Name", XamlNamespace) ?? r.GetAttribute("Name"); |
||||
bool isEmptyElement = r.IsEmptyElement; |
||||
|
||||
if (!string.IsNullOrEmpty(name)) { |
||||
IReturnType type = TypeFromXmlNode(cu, r); |
||||
|
||||
// Use position of Name attribute for field region
|
||||
//if (!r.MoveToAttribute("Name", XamlNamespace)) {
|
||||
// r.MoveToAttribute("Name");
|
||||
//}
|
||||
DomRegion position = new DomRegion(r.LineNumber, r.LinePosition, r.LineNumber, r.LinePosition + name.Length); |
||||
c.Fields.Add(new DefaultField(type, name, ModifierEnum.Internal, position, c)); |
||||
} |
||||
|
||||
if (isEmptyElement) |
||||
return; |
||||
while (r.Read()) { |
||||
if (r.NodeType == XmlNodeType.Element) { |
||||
ParseXamlElement(cu, c, r); |
||||
} |
||||
else if (r.NodeType == XmlNodeType.Comment) { |
||||
foreach (string tag in lexerTags) { |
||||
if (r.Value.Contains(tag)) { |
||||
cu.TagComments.Add(new TagComment(r.Value, new DomRegion(r.LineNumber, r.LinePosition, r.LineNumber, r.LinePosition + r.Value.Length))); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
else if (r.NodeType == XmlNodeType.EndElement) { |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public IExpressionFinder CreateExpressionFinder(string fileName) |
||||
{ |
||||
return XamlExpressionFinder.Instance; |
||||
} |
||||
|
||||
public IResolver CreateResolver() |
||||
{ |
||||
return new XamlResolver(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,349 @@
@@ -0,0 +1,349 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3539 $</version>
|
||||
// </file>
|
||||
|
||||
using ICSharpCode.XmlEditor; |
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Xml; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
|
||||
namespace ICSharpCode.XamlBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Description of XamlResolver.
|
||||
/// </summary>
|
||||
public class XamlResolver : IResolver |
||||
{ |
||||
IClass callingClass; |
||||
string resolveExpression; |
||||
XamlExpressionContext context; |
||||
ParseInformation parseInfo; |
||||
int caretLineNumber, caretColumn; |
||||
|
||||
bool IsReaderAtTarget(XmlTextReader r) |
||||
{ |
||||
if (r.LineNumber > caretLineNumber) |
||||
return true; |
||||
else if (r.LineNumber == caretLineNumber) |
||||
return r.LinePosition >= caretColumn; |
||||
else |
||||
return false; |
||||
} |
||||
|
||||
public ResolveResult Resolve(ExpressionResult expressionResult, ParseInformation parseInfo, string fileContent) |
||||
{ |
||||
this.resolveExpression = expressionResult.Expression; |
||||
this.parseInfo = parseInfo; |
||||
this.caretLineNumber = expressionResult.Region.BeginLine; |
||||
this.caretColumn = expressionResult.Region.BeginColumn; |
||||
this.callingClass = parseInfo.BestCompilationUnit.GetInnermostClass(caretLineNumber, caretColumn); |
||||
this.context = expressionResult.Context as XamlExpressionContext; |
||||
if (context == null) |
||||
return null; |
||||
try { |
||||
using (XmlTextReader r = new XmlTextReader(new StringReader(fileContent))) { |
||||
r.WhitespaceHandling = WhitespaceHandling.Significant; |
||||
// move reader to correct position
|
||||
while (r.Read() && !IsReaderAtTarget(r)) { } |
||||
|
||||
if (string.IsNullOrEmpty(context.AttributeName)) { |
||||
return ResolveElementName(r); |
||||
} |
||||
else if (context.InAttributeValue) { |
||||
MemberResolveResult mrr = ResolveAttribute(r, context.AttributeName); |
||||
if (mrr != null) { |
||||
return ResolveAttributeValue(mrr.ResolvedMember, resolveExpression); |
||||
} |
||||
} |
||||
else { |
||||
// in attribute name
|
||||
return ResolveAttribute(r, resolveExpression); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
catch (XmlException) { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
ResolveResult ResolveElementName(XmlReader r) |
||||
{ |
||||
string xmlNamespace; |
||||
string name; |
||||
if (resolveExpression.Contains(":")) { |
||||
string prefix = resolveExpression.Substring(0, resolveExpression.IndexOf(':')); |
||||
name = resolveExpression.Substring(resolveExpression.IndexOf(':') + 1); |
||||
xmlNamespace = r.LookupNamespace(prefix); |
||||
} |
||||
else { |
||||
xmlNamespace = r.LookupNamespace(""); |
||||
name = resolveExpression; |
||||
} |
||||
if (name.Contains(".")) { |
||||
string propertyName = name.Substring(name.IndexOf('.') + 1); |
||||
name = name.Substring(0, name.IndexOf('.')); |
||||
return ResolveProperty(xmlNamespace, name, propertyName, true); |
||||
} |
||||
else { |
||||
IProjectContent pc = parseInfo.BestCompilationUnit.ProjectContent; |
||||
IReturnType resolvedType = XamlCompilationUnit.FindType(pc, xmlNamespace, name); |
||||
IClass resolvedClass = resolvedType != null ? resolvedType.GetUnderlyingClass() : null; |
||||
if (resolvedClass != null) { |
||||
return new TypeResolveResult(callingClass, null, resolvedClass); |
||||
} |
||||
else { |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
|
||||
MemberResolveResult ResolveProperty(string xmlNamespace, string className, string propertyName, bool allowAttached) |
||||
{ |
||||
IProjectContent pc = parseInfo.BestCompilationUnit.ProjectContent; |
||||
IReturnType resolvedType = XamlCompilationUnit.FindType(pc, xmlNamespace, className); |
||||
if (resolvedType != null && resolvedType.GetUnderlyingClass() != null) { |
||||
IMember member = resolvedType.GetProperties().Find(delegate(IProperty p) { return p.Name == propertyName; }); |
||||
if (member == null) { |
||||
member = resolvedType.GetEvents().Find(delegate(IEvent p) { return p.Name == propertyName; }); |
||||
} |
||||
if (member == null && allowAttached) { |
||||
member = resolvedType.GetMethods().Find( |
||||
delegate(IMethod p) { |
||||
return p.IsStatic && p.Parameters.Count == 1 && p.Name == "Get" + propertyName; |
||||
}); |
||||
} |
||||
if (member != null) |
||||
return new MemberResolveResult(callingClass, null, member); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
MemberResolveResult ResolveAttribute(XmlReader r, string attributeName) |
||||
{ |
||||
if (context.ElementPath.Elements.Count == 0) { |
||||
return null; |
||||
} |
||||
string attributeXmlNamespace; |
||||
if (attributeName.Contains(":")) { |
||||
attributeXmlNamespace = r.LookupNamespace(attributeName.Substring(0, attributeName.IndexOf(':'))); |
||||
attributeName = attributeName.Substring(attributeName.IndexOf(':') + 1); |
||||
} |
||||
else { |
||||
attributeXmlNamespace = r.LookupNamespace(""); |
||||
} |
||||
if (attributeName.Contains(".")) { |
||||
string className = attributeName.Substring(0, attributeName.IndexOf('.')); |
||||
attributeName = attributeName.Substring(attributeName.IndexOf('.') + 1); |
||||
return ResolveProperty(attributeXmlNamespace, className, attributeName, true); |
||||
} |
||||
else { |
||||
ICSharpCode.XmlEditor.QualifiedName lastElement = context.ElementPath.Elements[context.ElementPath.Elements.Count - 1]; |
||||
return ResolveProperty(lastElement.Namespace, lastElement.Name, attributeName, false); |
||||
} |
||||
} |
||||
|
||||
ResolveResult ResolveAttributeValue(IMember propertyOrEvent, string expression) |
||||
{ |
||||
if (propertyOrEvent == null) |
||||
return null; |
||||
if (propertyOrEvent is IEvent) { |
||||
return new MethodGroupResolveResult(callingClass, null, callingClass.DefaultReturnType, expression); |
||||
} |
||||
|
||||
if (propertyOrEvent.Name == "Name" && callingClass != null) { |
||||
foreach (IField f in callingClass.Fields) { |
||||
if (f.Name == expression) |
||||
return new MemberResolveResult(callingClass, null, f); |
||||
} |
||||
} |
||||
|
||||
IReturnType type = propertyOrEvent.ReturnType; |
||||
if (type == null) return null; |
||||
IClass c = type.GetUnderlyingClass(); |
||||
if (c == null) return null; |
||||
|
||||
if (c.ClassType == ClassType.Enum) { |
||||
foreach (IField f in c.Fields) { |
||||
if (f.Name == expression) |
||||
return new MemberResolveResult(callingClass, null, f); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public ArrayList CtrlSpace(int caretLineNumber, int caretColumn, ParseInformation parseInfo, string fileContent, ExpressionContext expressionContext) |
||||
{ |
||||
this.parseInfo = parseInfo; |
||||
this.caretLineNumber = caretLineNumber; |
||||
this.caretColumn = caretColumn; |
||||
this.callingClass = parseInfo.BestCompilationUnit.GetInnermostClass(caretLineNumber, caretColumn); |
||||
this.context = expressionContext as XamlExpressionContext; |
||||
if (context == null) { |
||||
return null; |
||||
} |
||||
|
||||
if (context.AttributeName == null) { |
||||
return CtrlSpaceForElement(fileContent); |
||||
} |
||||
else if (context.InAttributeValue) { |
||||
return CtrlSpaceForAttributeValue(fileContent, context); |
||||
} |
||||
else { |
||||
return CtrlSpaceForAttributeName(fileContent, context); |
||||
} |
||||
} |
||||
|
||||
ArrayList CtrlSpaceForAttributeName(string fileContent, XamlExpressionContext context) |
||||
{ |
||||
if (context.ElementPath.Elements.Count == 0) |
||||
return null; |
||||
QualifiedName lastElement = context.ElementPath.Elements[context.ElementPath.Elements.Count - 1]; |
||||
XamlCompilationUnit cu = parseInfo.BestCompilationUnit as XamlCompilationUnit; |
||||
if (cu == null) |
||||
return null; |
||||
IReturnType rt = cu.CreateType(lastElement.Namespace, lastElement.Name); |
||||
if (rt == null) |
||||
return null; |
||||
ArrayList list = new ArrayList(); |
||||
foreach (IProperty p in rt.GetProperties()) { |
||||
if (p.IsPublic && p.CanSet) { |
||||
list.Add(p); |
||||
} |
||||
} |
||||
return list; |
||||
} |
||||
|
||||
ArrayList CtrlSpaceForAttributeValue(string fileContent, XamlExpressionContext context) |
||||
{ |
||||
ArrayList attributes = CtrlSpaceForAttributeName(fileContent, context); |
||||
if (attributes != null) { |
||||
foreach (IProperty p in attributes.OfType<IProperty>()) { |
||||
if (p.Name == context.AttributeName && p.ReturnType != null) { |
||||
IClass c = p.ReturnType.GetUnderlyingClass(); |
||||
if (c != null && c.ClassType == ClassType.Enum) { |
||||
return EnumCompletion(c); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
ArrayList EnumCompletion(IClass enumClass) |
||||
{ |
||||
ArrayList arr = new ArrayList(); |
||||
foreach (IField f in enumClass.Fields) { |
||||
arr.Add(f); |
||||
} |
||||
return arr; |
||||
} |
||||
|
||||
ArrayList CtrlSpaceForElement(string fileContent) |
||||
{ |
||||
using (XmlTextReader r = new XmlTextReader(new StringReader(fileContent))) { |
||||
try { |
||||
r.WhitespaceHandling = WhitespaceHandling.Significant; |
||||
// move reader to correct position
|
||||
while (r.Read() && !IsReaderAtTarget(r)) { } |
||||
} |
||||
catch (XmlException) { |
||||
} |
||||
ArrayList result = new ArrayList(); |
||||
IProjectContent pc = parseInfo.BestCompilationUnit.ProjectContent; |
||||
|
||||
resolveExpression = r.Name; |
||||
TypeResolveResult rr = ResolveElementName(r) as TypeResolveResult; |
||||
if (rr != null) { |
||||
AddPropertiesForType(result, r, rr); |
||||
} |
||||
|
||||
foreach (var ns in r.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml)) { |
||||
ArrayList list = XamlCompilationUnit.GetNamespaceMembers(pc, ns.Value); |
||||
if (list != null) { |
||||
foreach (IClass c in list.OfType<IClass>()) { |
||||
if (c.ClassType != ClassType.Class) |
||||
continue; |
||||
if (c.IsAbstract && c.IsStatic) |
||||
continue; |
||||
if (c.ClassInheritanceTree.Any(b => b.FullyQualifiedName == "System.Attribute")) |
||||
continue; |
||||
if (!c.Methods.Any(m => m.IsConstructor && m.IsPublic)) |
||||
continue; |
||||
if (string.IsNullOrEmpty(ns.Key)) |
||||
result.Add(c); |
||||
else |
||||
result.Add(new XamlCompletionClass(c, ns.Key)); |
||||
} |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
} |
||||
|
||||
void AddPropertiesForType(ArrayList result, XmlTextReader r, TypeResolveResult rr) |
||||
{ |
||||
if (rr.ResolvedType != null) { |
||||
foreach (IProperty p in rr.ResolvedType.GetProperties()) { |
||||
if (!p.IsPublic) |
||||
continue; |
||||
if (!p.CanSet && !IsCollectionType(p.ReturnType)) |
||||
continue; |
||||
string propPrefix = p.DeclaringType.Name; |
||||
if (!string.IsNullOrEmpty(r.Prefix)) |
||||
propPrefix = r.Prefix + ":" + propPrefix; |
||||
result.Add(new XamlCompletionProperty(p, propPrefix)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool IsCollectionType(IReturnType rt) |
||||
{ |
||||
if (rt == null) |
||||
return false; |
||||
return rt.GetMethods().Any(m => m.Name == "Add" && m.IsPublic); |
||||
} |
||||
|
||||
class XamlCompletionClass : DefaultClass, IEntity |
||||
{ |
||||
string newName; |
||||
|
||||
public XamlCompletionClass(IClass baseClass, string prefix) |
||||
: base(baseClass.CompilationUnit, baseClass.FullyQualifiedName) |
||||
{ |
||||
this.Modifiers = baseClass.Modifiers; |
||||
newName = prefix + ":" + baseClass.Name; |
||||
} |
||||
|
||||
string IEntity.Name |
||||
{ |
||||
get { return newName; } |
||||
} |
||||
} |
||||
|
||||
class XamlCompletionProperty : DefaultProperty, IEntity |
||||
{ |
||||
string newName; |
||||
|
||||
public XamlCompletionProperty(IProperty baseProperty, string prefix) |
||||
: base(baseProperty.DeclaringType, baseProperty.Name) |
||||
{ |
||||
this.Modifiers = baseProperty.Modifiers; |
||||
newName = prefix + "." + baseProperty.Name; |
||||
} |
||||
|
||||
string IEntity.Name |
||||
{ |
||||
get { return newName; } |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,115 @@
@@ -0,0 +1,115 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision: 2667$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.ComponentModel; |
||||
using System.IO; |
||||
using System.Windows.Controls; |
||||
|
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using ICSharpCode.WpfDesign.Designer.XamlBackend; |
||||
using ICSharpCode.Xaml; |
||||
|
||||
namespace ICSharpCode.WpfDesign.AddIn |
||||
{ |
||||
abstract class AbstractEventHandlerService : IEventHandlerService |
||||
{ |
||||
WpfPrimaryViewContent viewContent; |
||||
|
||||
protected AbstractEventHandlerService(WpfPrimaryViewContent viewContent) |
||||
{ |
||||
if (viewContent == null) |
||||
throw new ArgumentNullException("viewContent"); |
||||
this.viewContent = viewContent; |
||||
} |
||||
|
||||
protected IProjectContent GetProjectContent() |
||||
{ |
||||
IProject p = ProjectService.OpenSolution.FindProjectContainingFile(viewContent.PrimaryFileName); |
||||
if (p != null) |
||||
return ParserService.GetProjectContent(p) ?? ParserService.DefaultProjectContent; |
||||
else |
||||
return ParserService.DefaultProjectContent; |
||||
} |
||||
|
||||
protected IClass GetDesignedClass() |
||||
{ |
||||
var model = viewContent.Context.ModelService as XamlModelService; |
||||
if (model != null) { |
||||
string className = model.ClassName; |
||||
if (!string.IsNullOrEmpty(className)) { |
||||
return GetProjectContent().GetClass(className, 0); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
protected IClass GetDesignedClassCodeBehindPart(IClass c) |
||||
{ |
||||
CompoundClass compound = c as CompoundClass; |
||||
if (compound != null) { |
||||
c = null; |
||||
foreach (IClass part in compound.Parts) { |
||||
if (string.IsNullOrEmpty(part.CompilationUnit.FileName)) |
||||
continue; |
||||
if (XamlConstants.HasXamlExtension(part.CompilationUnit.FileName)) |
||||
continue; |
||||
if (c == null || c.CompilationUnit.FileName.Length > part.CompilationUnit.FileName.Length) |
||||
c = part; |
||||
} |
||||
} |
||||
return c; |
||||
} |
||||
|
||||
protected abstract void CreateEventHandlerInternal(Type eventHandlerType, string handlerName); |
||||
|
||||
public void CreateEventHandler(DesignItemProperty eventProperty) |
||||
{ |
||||
var item = eventProperty.DesignItem; |
||||
string handlerName = (string)eventProperty.ValueOnInstance; |
||||
|
||||
if (string.IsNullOrEmpty(handlerName)) { |
||||
if (string.IsNullOrEmpty(item.Name)) { |
||||
GenerateName(eventProperty.DesignItem); |
||||
} |
||||
handlerName = item.Name + "_" + eventProperty.Name; |
||||
eventProperty.SetValue(handlerName); |
||||
} |
||||
CreateEventHandlerInternal(eventProperty.ReturnType, handlerName); |
||||
} |
||||
|
||||
public DesignItemProperty GetDefaultEvent(DesignItem item) |
||||
{ |
||||
object[] attributes = item.ComponentType.GetCustomAttributes(typeof(DefaultEventAttribute), true); |
||||
if (attributes.Length == 1) { |
||||
DefaultEventAttribute dae = (DefaultEventAttribute)attributes[0]; |
||||
DesignItemProperty property = item.Properties.GetProperty(dae.Name); |
||||
if (property != null && property.IsEvent) { |
||||
return property; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
void GenerateName(DesignItem item) |
||||
{ |
||||
for (int i = 1; ; i++) { |
||||
try { |
||||
string name = item.ComponentType.Name + i; |
||||
name = char.ToLower(name[0]) + name.Substring(1); |
||||
item.Name = name; |
||||
break; |
||||
} |
||||
catch { |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision: 2667$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; |
||||
|
||||
namespace ICSharpCode.WpfDesign.AddIn |
||||
{ |
||||
sealed class CSharpEventHandlerService : AbstractEventHandlerService |
||||
{ |
||||
public CSharpEventHandlerService(WpfPrimaryViewContent viewContent) |
||||
: base(viewContent) |
||||
{ |
||||
} |
||||
|
||||
protected override void CreateEventHandlerInternal(Type eventHandlerType, string handlerName) |
||||
{ |
||||
IClass c = GetDesignedClass(); |
||||
if (c != null) { |
||||
foreach (IMethod m in c.Methods) { |
||||
if (m.Name == handlerName) { |
||||
FileService.JumpToFilePosition(m.DeclaringType.CompilationUnit.FileName, |
||||
m.Region.BeginLine - 1, m.Region.BeginColumn - 1); |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
c = GetDesignedClassCodeBehindPart(c); |
||||
if (c != null) { |
||||
ITextEditorControlProvider tecp = FileService.OpenFile(c.CompilationUnit.FileName) as ITextEditorControlProvider; |
||||
if (tecp != null) { |
||||
int lineNumber; |
||||
FormsDesigner.CSharpDesignerGenerator.CreateComponentEvent( |
||||
c, tecp.TextEditorControl.Document, eventHandlerType, handlerName, null, |
||||
out lineNumber); |
||||
tecp.TextEditorControl.ActiveTextAreaControl.JumpTo(lineNumber - 1); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 2577 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.IO; |
||||
using System.Windows.Markup; |
||||
|
||||
using ICSharpCode.SharpDevelop; |
||||
|
||||
namespace ICSharpCode.WpfDesign.AddIn |
||||
{ |
||||
/// <summary>
|
||||
/// Used to support loading Image.ImageSource.
|
||||
/// </summary>
|
||||
public class FileUriContext : IUriContext |
||||
{ |
||||
OpenedFile file; |
||||
|
||||
public FileUriContext(OpenedFile file) |
||||
{ |
||||
if (file == null) |
||||
throw new ArgumentNullException("file"); |
||||
this.file = file; |
||||
} |
||||
|
||||
public Uri BaseUri { |
||||
get { |
||||
return new Uri(file.FileName); |
||||
} |
||||
set { |
||||
throw new NotSupportedException(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Drawing; |
||||
using System.Windows; |
||||
using System.Windows.Interop; |
||||
using System.Windows.Markup; |
||||
using System.Windows.Media.Imaging; |
||||
|
||||
using ICSharpCode.Core.WinForms; |
||||
|
||||
namespace ICSharpCode.WpfDesign.AddIn |
||||
{ |
||||
class GetBitmapExtension : MarkupExtension |
||||
{ |
||||
public GetBitmapExtension(string key) |
||||
{ |
||||
this.key = key; |
||||
} |
||||
|
||||
static Dictionary<string, BitmapSource> cache = new Dictionary<string, BitmapSource>(); |
||||
|
||||
protected string key; |
||||
|
||||
public override object ProvideValue(IServiceProvider sp) |
||||
{ |
||||
lock (cache) { |
||||
BitmapSource result; |
||||
if (!cache.TryGetValue(key, out result)) { |
||||
result = GetBitmapSource(); |
||||
result.Freeze(); |
||||
cache[key] = result; |
||||
} |
||||
return result; |
||||
} |
||||
} |
||||
|
||||
BitmapSource GetBitmapSource() |
||||
{ |
||||
Bitmap bitmap = WinFormsResourceService.GetBitmap(key); |
||||
return Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, |
||||
Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
using System; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using System.Reflection; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.WpfDesign.Designer.Services; |
||||
using ICSharpCode.FormsDesigner.Services; |
||||
|
||||
namespace ICSharpCode.WpfDesign.AddIn |
||||
{ |
||||
public class IdeChooseClassService : ChooseClassServiceBase |
||||
{ |
||||
public override IEnumerable<Assembly> GetAssemblies() |
||||
{ |
||||
var pc = ParserService.CurrentProjectContent; |
||||
if (pc != null) { |
||||
var a = XamlMapper.TypeResolutionServiceInstance.LoadAssembly(pc); |
||||
if (a != null) yield return a; |
||||
foreach (var r in pc.ReferencedContents) { |
||||
a = XamlMapper.TypeResolutionServiceInstance.LoadAssembly(r); |
||||
if (a != null) yield return a; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,62 @@
@@ -0,0 +1,62 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 2577 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Reflection; |
||||
using ICSharpCode.WpfDesign.XamlDom; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using TypeResolutionService = ICSharpCode.FormsDesigner.Services.TypeResolutionService; |
||||
|
||||
namespace ICSharpCode.WpfDesign.AddIn |
||||
{ |
||||
public class MyTypeFinder : XamlTypeFinder |
||||
{ |
||||
OpenedFile file; |
||||
|
||||
public static MyTypeFinder Create(OpenedFile file) |
||||
{ |
||||
MyTypeFinder f = new MyTypeFinder(); |
||||
f.file = file; |
||||
f.ImportFrom(CreateWpfTypeFinder()); |
||||
return f; |
||||
} |
||||
|
||||
public override Assembly LoadAssembly(string name) |
||||
{ |
||||
if (string.IsNullOrEmpty(name)) { |
||||
IProjectContent pc = GetProjectContent(file); |
||||
if (pc != null) { |
||||
return TypeResolutionService.LoadAssembly(pc); |
||||
} |
||||
return null; |
||||
} else { |
||||
return base.LoadAssembly(name); |
||||
} |
||||
} |
||||
|
||||
public override XamlTypeFinder Clone() |
||||
{ |
||||
MyTypeFinder copy = new MyTypeFinder(); |
||||
copy.file = this.file; |
||||
copy.ImportFrom(this); |
||||
return copy; |
||||
} |
||||
|
||||
internal static IProjectContent GetProjectContent(OpenedFile file) |
||||
{ |
||||
if (ProjectService.OpenSolution != null && file != null) { |
||||
IProject p = ProjectService.OpenSolution.FindProjectContainingFile(file.FileName); |
||||
if (p != null) { |
||||
return ParserService.GetProjectContent(p); |
||||
} |
||||
} |
||||
return ParserService.DefaultProjectContent; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
|
||||
<Button |
||||
x:Class="ICSharpCode.WpfDesign.AddIn.ObjectEditor" |
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
Content="New..." |
||||
HorizontalAlignment="Right" |
||||
> |
||||
</Button> |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
using System; |
||||
using System.Windows; |
||||
using ICSharpCode.WpfDesign.PropertyGrid; |
||||
using ICSharpCode.WpfDesign.Designer.Services; |
||||
|
||||
namespace ICSharpCode.WpfDesign.AddIn |
||||
{ |
||||
[PropertyEditor(typeof(FrameworkElement), "DataContext")] |
||||
public partial class ObjectEditor |
||||
{ |
||||
public ObjectEditor() |
||||
{ |
||||
InitializeComponent(); |
||||
} |
||||
|
||||
public PropertyNode PropertyNode { |
||||
get { return DataContext as PropertyNode; } |
||||
} |
||||
|
||||
protected override void OnClick() |
||||
{ |
||||
var s = PropertyNode.Services.GetService<ChooseClassServiceBase>(); |
||||
if (s != null) { |
||||
var c = s.ChooseClass(); |
||||
if (c != null) { |
||||
PropertyNode.Value = Activator.CreateInstance(c); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3519 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
|
||||
namespace ICSharpCode.WpfDesign.AddIn |
||||
{ |
||||
public class OutlineViewPad : AbstractPadContent |
||||
{ |
||||
public override System.Windows.Forms.Control Control |
||||
{ |
||||
get { return WpfTools.OutlineHost; } |
||||
} |
||||
|
||||
//SharpDevelopElementHost host = new SharpDevelopElementHost();
|
||||
|
||||
//TextBlock notAvailableTextBlock = new TextBlock {
|
||||
// Text = StringParser.Parse("${res:ICSharpCode.SharpDevelop.Gui.OutlinePad.NotAvailable}"),
|
||||
// TextWrapping = TextWrapping.Wrap
|
||||
//};
|
||||
|
||||
//public OutlineViewPad()
|
||||
//{
|
||||
// WorkbenchSingleton.Workbench.ActiveViewContentChanged += WorkbenchActiveViewContentChanged;
|
||||
// WorkbenchActiveViewContentChanged(null, null);
|
||||
//}
|
||||
|
||||
//void WorkbenchActiveViewContentChanged(object sender, EventArgs e)
|
||||
//{
|
||||
// WpfSecondaryViewContent wpfView = WorkbenchSingleton.Workbench.ActiveViewContent as WpfSecondaryViewContent;
|
||||
// host.ViewContent = wpfView;
|
||||
// if (wpfView != null) {
|
||||
// host.Child = wpfView.Outline;
|
||||
// } else {
|
||||
// host.Child = notAvailableTextBlock;
|
||||
// }
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// The <see cref="System.Windows.Forms.Control"/> representing the pad
|
||||
///// </summary>
|
||||
//public override System.Windows.Forms.Control Control {
|
||||
// get {
|
||||
// return host;
|
||||
// }
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// Cleans up all used resources
|
||||
///// </summary>
|
||||
//public override void Dispose()
|
||||
//{
|
||||
// host.Dispose();
|
||||
// base.Dispose();
|
||||
//}
|
||||
} |
||||
} |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
|
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3506 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; |
||||
using ICSharpCode.WpfDesign.Designer.XamlBackend; |
||||
|
||||
namespace ICSharpCode.WpfDesign.AddIn |
||||
{ |
||||
public class PropertyDescriptionService : IPropertyDescriptionService |
||||
{ |
||||
public object GetDescription(DesignItemProperty property) |
||||
{ |
||||
var p = property as XamlDesignItemProperty; |
||||
var m = XamlMapper.GetDomMember(p.XamlProperty.Member); |
||||
return CodeCompletionData.GetDocumentation(m.Documentation); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,123 @@
@@ -0,0 +1,123 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3519 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using System.Windows.Forms.Integration; |
||||
using System.Windows.Input; |
||||
using System.Windows.Threading; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.WpfDesign.Designer; |
||||
|
||||
namespace ICSharpCode.WpfDesign.AddIn |
||||
{ |
||||
/// <summary>
|
||||
/// Hosts a WPF element inside a Windows.Forms application.
|
||||
/// </summary>
|
||||
public class SharpDevelopElementHost : ElementHost, IUndoHandler, IClipboardHandler |
||||
{ |
||||
public SharpDevelopElementHost(UIElement child) |
||||
{ |
||||
Child = child; |
||||
|
||||
if (!registeredErrorHandler) { |
||||
registeredErrorHandler = true; |
||||
Dispatcher.CurrentDispatcher.UnhandledException += CurrentDispatcher_UnhandledException; |
||||
} |
||||
} |
||||
|
||||
[ThreadStatic] |
||||
static bool registeredErrorHandler; |
||||
|
||||
static void CurrentDispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) |
||||
{ |
||||
ICSharpCode.Core.MessageService.ShowError(e.Exception, "Unhandled WPF exception"); |
||||
e.Handled = true; |
||||
} |
||||
|
||||
ICommandService CurrentCommandService |
||||
{ |
||||
get |
||||
{ |
||||
if (WpfTools.ActiveContext != null) { |
||||
return WpfTools.ActiveContext.CommandService; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public bool EnableUndo |
||||
{ |
||||
get { return CurrentCommandService != null && CurrentCommandService.CanUndo(); } |
||||
} |
||||
|
||||
public bool EnableRedo |
||||
{ |
||||
get { return CurrentCommandService != null && CurrentCommandService.CanRedo(); } |
||||
} |
||||
|
||||
public bool EnableCopy |
||||
{ |
||||
get { return CurrentCommandService != null && CurrentCommandService.CanCopy(); } |
||||
} |
||||
|
||||
public bool EnablePaste |
||||
{ |
||||
get { return CurrentCommandService != null && CurrentCommandService.CanPaste(); } |
||||
} |
||||
|
||||
public bool EnableCut |
||||
{ |
||||
get { return CurrentCommandService != null && CurrentCommandService.CanCut(); } |
||||
} |
||||
|
||||
public bool EnableSelectAll |
||||
{ |
||||
get { return CurrentCommandService != null && CurrentCommandService.CanSelectAll(); } |
||||
} |
||||
|
||||
public bool EnableDelete |
||||
{ |
||||
get { return CurrentCommandService != null && CurrentCommandService.CanDelete(); } |
||||
} |
||||
|
||||
public void Undo() |
||||
{ |
||||
CurrentCommandService.Undo(); |
||||
} |
||||
|
||||
public void Redo() |
||||
{ |
||||
CurrentCommandService.Redo(); |
||||
} |
||||
|
||||
public void Copy() |
||||
{ |
||||
CurrentCommandService.Copy(); |
||||
} |
||||
|
||||
public void Paste() |
||||
{ |
||||
CurrentCommandService.Paste(); |
||||
} |
||||
|
||||
public void Cut() |
||||
{ |
||||
CurrentCommandService.Cut(); |
||||
} |
||||
|
||||
public void SelectAll() |
||||
{ |
||||
CurrentCommandService.SelectAll(); |
||||
} |
||||
|
||||
public void Delete() |
||||
{ |
||||
CurrentCommandService.Delete(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision: 2667$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using System.Windows.Forms; |
||||
using System.Windows.Interop; |
||||
using System.Windows.Media; |
||||
|
||||
namespace ICSharpCode.WpfDesign.AddIn |
||||
{ |
||||
sealed class WpfAndWinFormsTopLevelWindowService : ITopLevelWindowService |
||||
{ |
||||
public ITopLevelWindow GetTopLevelWindow(UIElement element) |
||||
{ |
||||
Window window = Window.GetWindow(element); |
||||
if (window != null) { |
||||
return new WpfTopLevelWindow(window); |
||||
} |
||||
HwndSource hwndSource = PresentationSource.FromVisual(element) as HwndSource; |
||||
if (hwndSource != null) { |
||||
Control ctl = Control.FromChildHandle(hwndSource.Handle); |
||||
if (ctl != null) { |
||||
Form form = ctl.FindForm(); |
||||
if (form != null) { |
||||
return new WindowsFormsTopLevelWindow(form); |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
sealed class WpfTopLevelWindow : ITopLevelWindow |
||||
{ |
||||
Window window; |
||||
|
||||
public WpfTopLevelWindow(Window window) |
||||
{ |
||||
this.window = window; |
||||
} |
||||
|
||||
public void SetOwner(Window child) |
||||
{ |
||||
child.Owner = window; |
||||
} |
||||
|
||||
public bool Activate() |
||||
{ |
||||
return window.Activate(); |
||||
} |
||||
} |
||||
|
||||
sealed class WindowsFormsTopLevelWindow : ITopLevelWindow |
||||
{ |
||||
Form form; |
||||
|
||||
public WindowsFormsTopLevelWindow(Form form) |
||||
{ |
||||
this.form = form; |
||||
} |
||||
|
||||
public void SetOwner(Window child) |
||||
{ |
||||
(new WindowInteropHelper(child)).Owner = form.Handle; |
||||
} |
||||
|
||||
public bool Activate() |
||||
{ |
||||
return form.Focus(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3497 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.IO; |
||||
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; |
||||
using ICSharpCode.SharpDevelop; |
||||
|
||||
namespace ICSharpCode.WpfDesign.AddIn |
||||
{ |
||||
public class WpfPrimaryDisplayBinding : TextEditorDisplayBinding |
||||
{ |
||||
protected override TextEditorDisplayBindingWrapper CreateWrapper(OpenedFile file) |
||||
{ |
||||
return new WpfPrimaryViewContent(file); |
||||
} |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue