lundi 21 novembre 2011

C# WPF, Dynamic Loading / Late Binding / Reflection with AvalonEdit

The point here is to optionnaly allow to use AvalonEdit in an (wpf) application.


The basics

Specific using:
using System.IO;
using System.Reflection;
using System.Xml; //only for "the not so basic"
As you can see, none of them concerns AvanlonEdit...

When to Load :
String AvalonEditDllName = "ICSharpCode.AvalonEdit.dll";
if ( File.Exists(AvalonEditDllName) ) {/*...*/}

How to load:
Assembly u = Assembly.LoadFile(Path.GetFullPath(AvalonEditDllName));

What to instanciate:
Type tAvalonEditTextEditor = u.GetType("ICSharpCode.AvalonEdit.TextEditor");
if ( tAvalonEditTextEditor != null ) {/*...*/}

How to instanciate:
System.Windows.UIElement aeui = 
    (System.Windows.UIElement)Activator.CreateInstance(tAvalonEditTextEditor);

From now, you can use your System.Windows.UIElement in your WPF form just like this:
MainGrid.Children.Add(aeui);
where MainGrid is, for example, a System.Windows.Controls.Grid.

The basics of properties

Do you want line numbers ?
First let's look for the property of the type :
PropertyInfo propShowLineNumbers = 
    tAvalonEditTextEditor.GetProperty("ShowLineNumbers");
Then let's make the property true :
propShowLineNumbers.SetValue(aeui, true, null);

The not so basic of properties

And what about syntax hihgligting ?? Good question indeed !
Some more types and properties:
Type tAvalonEditHightingLoader = 
    u.GetType("ICSharpCode.AvalonEdit.Highlighting.Xshd.HighlightingLoader");
Type tAvalonEditHightingManager = 
    u.GetType("ICSharpCode.AvalonEdit.Highlighting.HighlightingManager");

PropertyInfo propSyntaxHighlighting = tAvalonEditTextEditor.GetProperty("SyntaxHighlighting");
PropertyInfo spropAEHMInstance = tAvalonEditHightingManager.GetProperty("Instance");

And the loading himself (I try to keep the variables consistant with the previous pieces of code):
String XshdFileName = "t-sql.xshd";
using ( XmlTextReader reader = new XmlTextReader(XshdFileName) ) {
    propSyntaxHighlighting.SetValue( //let's set the property of the text editor
        aeui,
        tAvalonEditHightingLoader.InvokeMember(
            "Load", //by loading the xshd file with HightingLoader.Load
            BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | 
                BindingFlags.InvokeMethod,
            null, null,
                   //with the following parameters
            new Object[] { reader, spropAEHMInstance.GetValue(null, null) }
                   //one of them being the static property
                   //HighlightingManager.Instance
        ),
        null
    );
 }

Aucun commentaire:

Enregistrer un commentaire