WPF / XAML:如何引用未在任何命名空间中定义的类
我正在执行一个尝试定义和打开WPF窗口的roslyn脚本。
除此之外,我的脚本
- 定义附加行为
- 定义一个XAML字符串,基于此我创建一个WPF窗口。 在这个XAML代码中,我想使用我的脚本中定义的TextBoxCursorPositionBehavior。
我的脚本(.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看起来像
但问题是,如何在XAML中正确引用TextBoxCursorPositionBehavior?
Roslyn不允许在脚本文件中使用命名空间,因此TextBoxCursorPositionBehavior必须在命名空间之外定义(即我认为它将落入全局命名空间)。
但是,我怎样才能在XAML中引用它? 我尝试使用“clr-namespace :; assembly =”+ typeof(TextBoxCursorPositionBehavior).ToString()来定义命名空间引用,但这不起作用。 简单地说“clr-namespace:”(即没有汇编引用)也不起作用。
有没有办法从XAML定义中引用TextBoxCursorPositionBehavior?
在您的代码而不是汇编中,您使用:
typeof(TextBoxCursorPositionBehavior).ToString()
这不是程序集名称。 将其更改为:
parserContext.XmlnsDictionary.Add("behaviors", "clr-namespace:;assembly=" + Assembly.GetExecutingAssembly().FullName);
它应该工作正常(至少适合我,但我不测试Roslyn脚本,但只是常规的WPF应用程序)。
我想我知道发生了什么…… Roslyn为脚本创建了一个自定义的Submission类型,似乎所有东西 – 包括TextBoxCursorPointerBehavior的定义 – 都是这个提交类型的子类。 也就是说,
var inst = new TextBoxCursorPositionBehavior(); string typeName = inst.GetType().FullName;
typeName不是“TextBoxCursorPointerBehavior”,而是“Submission#0 + TextBoxCursorPositionBehavior”。
同时,我不能从XAML中引用它(例如通过行为:提交#0 + TextBoxCursorPositionBehavior.TrackCaretIndex =“True”),因为它不会正确解析名称(#是一个无效的标记)。
从理论上讲,有可能将Roslyn的提交类型重命名为可通过XAML实际引用的内容 – 但在我的情况下,我不能这样做。
遗憾的是,目前我没有看到任何解决方案,除了可能将此代码外包给一个单独的预编译DLL(但这不是脚本编写的重点)