我将FlowDocument与BlockUIContainer和InlineUIContainer元素一起使用,这些元素包含(或作为基类)一些自定义块-SVG,数学公式等。因此,使用Selection.Load(stream,DataFormats.XamlPackage)不能正常工作,因为序列化将删除*的内容UIContainers,除非Child属性是Microsoft参考源中提供的图像:
private static void WriteStartXamlElement(...)
{
...
if ((inlineUIContainer == null || !(inlineUIContainer.Child is Image)) &&
(blockUIContainer == null || !(blockUIContainer.Child is Image)))
{
...
elementTypeStandardized = TextSchema.GetStandardElementType(elementType, /*reduceElement:*/true);
}
...
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,唯一的选择是使用可以完美运行的XamlWriter.Save和XamlReader.Load,序列化和反序列化FlowDocument的所有必需属性和对象,但必须手动实现Copy + Paste作为Copy +的默认实现粘贴使用Selection.Load / Save。
复制/粘贴非常重要,因为它还用于处理RichTextBox控件中或控件之间的元素拖动-无需自定义拖动代码即可操作对象的唯一方法。
这就是为什么我要使用FlowDocument序列化实现复制/粘贴,但是不幸的是,它存在一些问题:
显然,无法将对象从一个文档中删除并添加到另一个文档中(我最近发现了一个死胡同):'InlineCollection'元素无法插入树中,因为它已经是树的子级了。
[TextElementCollection.cs]
public void InsertAfter(TextElementType previousSibling, TextElementType newItem)
{
...
if (previousSibling.Parent != this.Parent)
throw new InvalidOperationException(System.Windows.SR.Get("TextElementCollection_PreviousSiblingDoesNotBelongToThisCollection", new object[1]
{
(object) previousSibling.GetType().Name
}));
...
}
Run Code Online (Sandbox Code Playgroud)
我想考虑在所有需要移到另一个文档的元素中使用反射来设置FrameworkContentElement._parent,但这是不得已而又肮脏的解决方案:
从理论上讲,我只能复制所需的对象:(可选)在选择的开头部分运行带有文本的文本,在and之间的所有段落和内联以及(可能)在结尾部分运行的部分,将它们封装在自定义类中,并使用进行序列化/反序列化XamlReader / XamlWriter。
这是带有部分工作的自定义复制/粘贴代码的自定义RichTextBox控件实现:
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents; …Run Code Online (Sandbox Code Playgroud) 我正在使用XamlReader.Parse(string)动态构建我的datatemplate.我遇到的问题是我无法在使用XamlReader创建的任何控件上放置任何事件.在网上做了一些研究后,我了解到这是XamlReader的一个已知限制.
我对WPF中的命令了解不多,但是我可以以某种方式使用它们来获得相同的结果吗?如果是这样的话?如果没有,我有什么办法可以在使用Xaml Reader创建的控件中处理我的代码中的事件?
下面是我创建的datatemplate的示例.我有窗口的代码隐藏中定义的MenuItem_Click事件处理程序将托管此datatemplate.
尝试运行时出现以下错误:System.Windows.Markup.XamlParseException未处理:无法从文本'MenuItem_Click'创建'Click'.
DataTemplate result = null;
StringBuilder sb = new StringBuilder();
sb.Append(@"<DataTemplate
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Grid Width=""Auto"" Height=""Auto"">
<TextBlock Text=""Hello"">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem
Header=""World""
Click=""MenuItem_Click""></MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</Grid>
</DataTemplate>");
result = XamlReader.Parse(sb.ToString()) as DataTemplate;
Run Code Online (Sandbox Code Playgroud) 试图在代码中加载generic.xaml但它会抛出XamlParseException.代码如下:
Uri uri = new Uri("Themes/Generic.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetResourceStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
ResourceDictionary resdict = (ResourceDictionary)reader.LoadAsync(info.Stream);
this.Resources.MergedDictionaries.Add(resdict);
Run Code Online (Sandbox Code Playgroud)
我们的想法是在基页中合并资源字典.然后派生页面可以使用{StaticResource DarkBrush}例如来自其基类的样式,颜色,画笔等.
但上面的代码抛出:
'',十六进制值0x0C,是无效字符.第1行,第1位.
generic.xaml文件是以标准方式在VS2010中创建的.试图将Build Action设置为Resource,但这也不起作用......
我从Microsoft 获得了代码示例.它用于加载页面.任何帮助将不胜感激.
我有一个WPF项目,AssemblyInfo.cs它将多个CLR名称空间组合到一个XML名称空间中:
[assembly: XmlnsDefinition("http://foo.bar", "MyLibary.Controls")]
[assembly: XmlnsDefinition("http://foo.bar", "MyLibary.Converters")]
Run Code Online (Sandbox Code Playgroud)
在XAML中,这样使用:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:fb="http://foo.bar">
<fb:FooButton IsEnabled="{Binding Something, Converter={fb:FooConverter}}"/>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
当XAML正常实例化时,这很有用,但现在我正在尝试使用我的项目动态加载XAML文件XamlReader.
问题:我似乎无法将多个CLR命名空间映射到单个XML命名空间.似乎添加到最后一个定义XamlTypeMapper是唯一一个持续存在的定义(例如,它破坏了以前的注册):
var parserContext = new ParserContext();
parserContext.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
parserContext.XmlnsDictionary.Add("fb", "http://foo.bar");
parserContext.XamlTypeMapper = new XamlTypeMapper(new string[] {"MyLibrary"});
parserContext.XamlTypeMapper.AddMappingProcessingInstruction("http://foo.bar", "MyLibrary.Converters", "MyLibrary");
parserContext.XamlTypeMapper.AddMappingProcessingInstruction("http://foo.bar", "MyLibrary.Controls", "MyLibrary");
...
var rootNode = XamlReader.Load(memeoryStream, parserContext) as FrameworkElement
Run Code Online (Sandbox Code Playgroud)
错误消息是:
'Cannot create unknown type '{http://foo.bar}MyConverter'.'
Run Code Online (Sandbox Code Playgroud)
如果所有代码都放在一个共同的CLR命名空间下,一切正常,但不幸的是,这不是选项.是否有人将多个CLR名称空间映射到单个XML名称空间,以便动态加载XAML内容?
提前致谢!
我有一个松散的XAML文件......
<Style
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyNamespace"
TargetType="{x:Type local:CustomControl}">
<Setter Property="HoverOpacity" Value="1.0"/>
</Style>
Run Code Online (Sandbox Code Playgroud)
...我想在运行时加载.当我这样做时,我得到一个异常,说明"类型引用找不到名为'CustomControl'的公共类型." 如何让松散的XAML知道我的命名空间?
我需要使用HoverOpacity哪个是依赖属性CustomControl.这是我目前用于加载XAML的代码:
var resource = Application.GetResourceStream(new Uri("pack://application:,,,/Assets/HoverStyle.xaml"));
XamlReader.Load(resource.Stream);
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我意识到XAML很简单,我可以插入Style代码,但这是一个hello world XAML; 它将变得更复杂,涉及动画等.
PS另一种解决方案是将XAML文件附加到从Panel派生的自定义控件(不会导致Visual Studio 2008崩溃)或者轻松附加触发器,数据触发器,进入操作和退出操作的方法自定义控件.
我有一个带有德语变音符号(下面的saml)的xaml现在当我尝试解析它时,我得到一个invalidchar错误.
当我不使用XamlParser Context时,它可以工作.但我必须使用它来设置一些类型映射
XAML:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:test="clr-namespace:BR.UI.Tests.Items;assembly=BR.UI.ViewLocator.Tests"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<test:SampleViewModel />
</UserControl.DataContext>
<Grid>
<Label>ö</Label>
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
解析它的代码
var context = new ParserContext();
var result = System.Windows.Markup.XamlReader.Parse(xaml,context);
Run Code Online (Sandbox Code Playgroud)
我找不到任何设置编码提示(这将是.net字符串UTF-16)我做错了什么?
我还尝试使用XmlParserContext注入编码.
var xmlcontext = new XmlParserContext(null, null, null, XmlSpace.Preserve,
Encoding.Unicode);
var context = new ParserContext(xmlcontext);
Run Code Online (Sandbox Code Playgroud)
但它没有帮助:-(
我需要做什么?有某种XAML编码吗?
为什么我不能抓住以下内容XamlParseException?

单击" 继续"按钮后,程序将继续执行正常操作(捕获异常并ex.Message在控制台上打印).
问题是Visual Studio异常对话框.为什么会出现?
xamlreader ×7
wpf ×6
c# ×4
xaml ×2
.net ×1
encoding ×1
exception ×1
flowdocument ×1
generic.xaml ×1
xamlwriter ×1