WPF / XAML:如何引用未在任何命名空间中定义的类

时间:2017-03-14 12:36:04

标签: c# wpf xaml roslyn

我正在执行尝试定义和打开WPF窗口的roslyn脚本。

除此之外,还有我的剧本

  1. 定义附加行为
  2. 定义了一个XAML字符串,基于此我创建了一个WPF窗口。在这个XAML代码中,我想使用我的脚本中定义的TextBoxCursorPositionBehavior。
  3. 我的脚本(.csx)文件类似于

    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();
          }
        }
    }
    

    并假设GUI_Definition.xaml看起来像

    <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>
    

    但问题是,如何在XAML中正确引用TextBoxCursorPositionBehavior?

    Roslyn不允许在脚本文件中使用命名空间,因此TextBoxCursorPositionBehavior必须在命名空间之外定义(即我认为它将落入全局命名空间)。

    但是,如何在XAML中引用它?我尝试使用&#34; clr-namespace :; assembly =&#34;来定义命名空间引用。 + typeof(TextBoxCursorPositionBehavior).ToString(),但这不起作用。 简单&#34; clr-namespace:&#34; (即没有装配参考)也不起作用。

    有没有办法在XAML定义中引用TextBoxCursorPositionBehavior?

2 个答案:

答案 0 :(得分:1)

在您的代码而不是汇编中使用:

typeof(TextBoxCursorPositionBehavior).ToString()

这不是程序集名称。将其更改为:

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

它应该可以正常工作(至少对我有用,但我不测试Roslyn脚本,只是常规的WPF应用程序)。

答案 1 :(得分:0)

我想我知道发生了什么...... Roslyn为脚本创建了一个自定义的Submission类型,似乎所有东西 - 包括TextBoxCursorPointerBehavior的定义 - 都是这个提交类型的子类。即,

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

typeName不会是&#34; TextBoxCursorPointerBehavior&#34;,而是&#34;提交#0 + TextBoxCursorPositionBehavior&#34;。

同时,我不能从XAML中引用它(例如通过行为:提交#0 + TextBoxCursorPositionBehavior.TrackCaretIndex =&#34; True&#34;)因为它无法正确解析名称(#是一个无效的令牌。)

理论上,可以将Roslyn的提交类型重命名为通过XAML实际引用的内容 - 但在我的情况下,我不能这样做。

目前遗憾的是,除了可能将此代码外包给一个单独的预编译DLL(但这不​​是脚本编写的重点)之外,我不会看到我的问题的任何解决方案。