WPF/XAML: 如何引用未在任何命名空间中定义的 class
WPF/XAML: How to reference class that is not defined within any namespace
我正在执行试图定义和打开 WPF 的 roslyn 脚本 window。
除其他外,我的脚本
- 定义附加行为
- 定义了一个 XAML 字符串,我基于它创建了一个 WPF Window。在此 XAML 代码中,我想使用脚本中定义的 TextBoxCursorPositionBehavior。
我的脚本 (.csx) 文件看起来类似于
public class TextBoxCursorPositionBehavior : DependencyObject
{
// see
}
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 中引用它?我尝试使用 "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 为脚本创建了自定义提交类型,并且似乎所有内容(包括 TextBoxCursorPointerBehavior 的定义)都是此提交类型的子class。即,
var inst = new TextBoxCursorPositionBehavior();
string typeName = inst.GetType().FullName;
typeName 不会是 "TextBoxCursorPointerBehavior",而是 "Submission#0+TextBoxCursorPositionBehavior".
同时,我无法从 XAML 引用它(例如通过 behaviors:Submission#0+TextBoxCursorPositionBehavior.TrackCaretIndex="True"),因为它不会解析名称正确(# 是那里的无效标记)。
理论上,可以通过 XAML 将 Roslyn 的提交类型重命名为实际可引用的内容 - 但就我而言,我不能这样做。
不幸的是,这意味着目前我没有看到任何解决我的问题的方法,除了可能将此代码外包给一个单独的预编译 DLL(但这也不是编写脚本的重点)
我正在执行试图定义和打开 WPF 的 roslyn 脚本 window。
除其他外,我的脚本
- 定义附加行为
- 定义了一个 XAML 字符串,我基于它创建了一个 WPF Window。在此 XAML 代码中,我想使用脚本中定义的 TextBoxCursorPositionBehavior。
我的脚本 (.csx) 文件看起来类似于
public class TextBoxCursorPositionBehavior : DependencyObject
{
// see
}
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 中引用它?我尝试使用 "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 为脚本创建了自定义提交类型,并且似乎所有内容(包括 TextBoxCursorPointerBehavior 的定义)都是此提交类型的子class。即,
var inst = new TextBoxCursorPositionBehavior();
string typeName = inst.GetType().FullName;
typeName 不会是 "TextBoxCursorPointerBehavior",而是 "Submission#0+TextBoxCursorPositionBehavior".
同时,我无法从 XAML 引用它(例如通过 behaviors:Submission#0+TextBoxCursorPositionBehavior.TrackCaretIndex="True"),因为它不会解析名称正确(# 是那里的无效标记)。
理论上,可以通过 XAML 将 Roslyn 的提交类型重命名为实际可引用的内容 - 但就我而言,我不能这样做。
不幸的是,这意味着目前我没有看到任何解决我的问题的方法,除了可能将此代码外包给一个单独的预编译 DLL(但这也不是编写脚本的重点)