3
votes

I'm executing a roslyn script that tries to define and open a WPF window.

Amongst other things, my script

  1. defines an attached behavior
  2. defines a XAML string, based on which I create a WPF Window. In this XAML code, I'd like to use the TextBoxCursorPositionBehavior defined in my script.

my script (.csx) file looks similar to

public class TextBoxCursorPositionBehavior : DependencyObject
{
    // see http://stackoverflow.com/questions/28233878/how-to-bind-to-caretindex-aka-curser-position-of-an-textbox
}

public class MyGui
{
    public void Show()
    {
      string xaml = File.ReadAllText(@"GUI_Definition.xaml");

      using (var sr = ToStream(xaml))
      {
        System.Windows.Markup.ParserContext parserContext = new System.Windows.Markup.ParserContext();
        parserContext.XmlnsDictionary.Add( "", "http://schemas.microsoft.com/winfx/2006/xaml/presentation" );
        parserContext.XmlnsDictionary.Add( "x", "http://schemas.microsoft.com/winfx/2006/xaml" );
        parserContext.XmlnsDictionary.Add("i","clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity");

        // ?? How  can i define this properly?
        parserContext.XmlnsDictionary.Add("behaviors", "clr-namespace:;assembly=" + typeof(TextBoxCursorPositionBehavior).Assembly.FullName);

        var window = (System.Windows.Window)XamlReader.Load(sr, parserContext);
        window.ShowDialog();
      }
    }
}

and assume the GUI_Definition.xaml looks like

<Window x:Class="System.Windows.Window" Height="300" Width="300" >
<Grid>
  <!-- how can i attach my behavior here properly? -->
  <TextBox behaviors:TextBoxCursorPositionBehavior.TrackCaretIndex="True"/>
</Grid>
</Window>

But the problem is, how can I reference TextBoxCursorPositionBehavior correctly in XAML?

Roslyn doesn't allow to use namespaces in script files, so TextBoxCursorPositionBehavior must be defined outstide of a namespace (i.e. I suppose it will fall into the global namespace).

But then, how can I reference it in XAML? I've tried defining the namespace reference with "clr-namespace:;assembly=" + typeof(TextBoxCursorPositionBehavior).ToString(), but that doesn't work. Simply "clr-namespace:" (i.e. without assembly reference) doesn't work either.

Is there any way to reference TextBoxCursorPositionBehavior from within the XAML definition?

2

2 Answers

1
votes

In your code instead of assembly you use:

typeof(TextBoxCursorPositionBehavior).ToString()

This is not an assembly name. Change it to:

parserContext.XmlnsDictionary.Add("behaviors", "clr-namespace:;assembly=" + Assembly.GetExecutingAssembly().FullName);

And it should work fine (at least works for me, but I don't test with Roslyn script but just regular WPF application).

0
votes

I think I know what's happening ... Roslyn creates a custom Submission type for scripts, and seems everything - including the definition of TextBoxCursorPointerBehavior - is a sub-class of this submission type. I.e.,

        var inst = new TextBoxCursorPositionBehavior();
        string typeName = inst.GetType().FullName;

typeName will not be "TextBoxCursorPointerBehavior", but rather "Submission#0+TextBoxCursorPositionBehavior".

At the same time, I can NOT reference this from XAML (e.g. by behaviors:Submission#0+TextBoxCursorPositionBehavior.TrackCaretIndex="True") as it won't parse the name correctly (# is an invalid token there).

In theory, it might be possible to rename Roslyn's submission type to something that is actually referencable via XAML - in my case though, I cannot do that.

Which unfortunately currently means I don't see any solution to my issue, other than possibly outsourcing this code to a separate pre-compiled DLL (but that's not quite the point of scripting either)