[英]How to display html content converted into xaml flowdocument in wpf application
[英]XAML WPF How to add inline background image on FlowDocument?
以下代码是将背景图像添加到流文档中
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<FlowDocument.Background>
<ImageBrush ImageSource="C:\licorice.jpg" />
</FlowDocument.Background>
<Paragraph>
<Run>Hello World!</Run>
</Paragraph>
</FlowDocument>
问题是,如何更改ImageSource,使其将图像数据作为字符串存储在xaml文件中? ImageBrush是密封的,所以我不能从中导出。 我正在寻找这样的东西:
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<FlowDocument.Background>
<InlineImageBrush base64Source="iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCA..." /> <!--does not work-->
</FlowDocument.Background>
<Paragraph>
<Run>Hello World!</Run>
</Paragraph>
</FlowDocument>
您可以通过以下机制(桌面WPF)执行此操作:
创建一个自定义DependencyObject
子类,该子类具有一个DependencyProperty
基本的64位图像字符串。 调用您的类,例如ImageData
。 完成此操作后,您可以将类的命名实例添加到FlowDocument.Resources
或Window.Resources
(或Grid.Resources
或其他)中,并在XAML中直接初始化base64字符串。
创建一个自定义IValueConverter,它将base64字符串转换为BitmapImage
。 将此作为命名的静态资源添加到Window.Resources
中。
对于要用作流文档背景的每个图像,将ImageData
添加到流文档本身的静态资源或更高级别的控件(例如窗口)中。 (注意-在我的旧版本的Visual Studio中,如果将图像资源添加到流文档本身,则表单设计器会感到困惑。但是,该应用程序已成功编译并运行。)
最后,为Background.ImageBrush.ImageSource
添加一个DataBinding
,将其链接到命名ImageData
资源的base 64字符串属性,并使用自定义转换器将其转换为图像。
详情如下所示。 首先,自定义ImageData
类非常简单:
public class ImageData : DependencyObject
{
public static readonly DependencyProperty Base64ImageDataProperty =
DependencyProperty.Register("Base64ImageData",
typeof(string),
typeof(ImageData));
public string Base64ImageData
{
get { return (string)(GetValue(Base64ImageDataProperty)); }
set { SetValue(Base64ImageDataProperty, value); }
}
}
接下来,自定义转换器和一些辅助实用程序与之配套:
public class Base64ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string base64String = value as string;
if (base64String == null)
return null;
return ImageHelper.Base64StringToBitmapImage(base64String);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
public static class ImageHelper
{
public static BitmapImage Base64StringToBitmapImage(string base64String)
{
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = new MemoryStream(Convert.FromBase64String(base64String));
bitmapImage.EndInit();
return bitmapImage;
}
public static string FileToBase64String(string filename)
{
using (var stream = File.Open(filename, FileMode.Open))
using (var reader = new BinaryReader(stream))
{
byte[] allData = reader.ReadBytes((int)reader.BaseStream.Length);
return Convert.ToBase64String(allData);
}
}
}
将其放置在窗口或应用程序的静态资源中,或放置在对您方便的其他中央位置,并可在整个应用程序中重复使用:
<Window x:Class="RichTextBoxInputPanel.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:w="clr-namespace:RichTextBoxInputPanel"
Title="RichTextBoxInputPanel" Height="600" Width="1200" Loaded="Window_Loaded">
<Window.Resources>
<w:Base64ImageConverter x:Key="Base64ImageConverter"></w:Base64ImageConverter>
</Window.Resources>
您也可以将其添加到流文件本身的静态资源,旁边的ImageData
如下图所示。
现在,将ImageData
添加到流程文档的资源中:
<FlowDocument >
<FlowDocument.Resources>
<w:ImageData x:Key="DocumentBackground" Base64ImageData="iVBORw0K...etc etc">
</w:ImageData>
</FlowDocument.Resources>
最后,为背景添加绑定属性:
<FlowDocument.Background>
<ImageBrush>
<ImageBrush.ImageSource>
<Binding Converter="{StaticResource Base64ImageConverter}"
Source="{StaticResource DocumentBackground}"
Path="Base64ImageData" Mode="OneWay"></Binding>
</ImageBrush.ImageSource>
</ImageBrush>
</FlowDocument.Background>
最后,如上所述,将静态ImageData
资源放在流文档本身上会导致WPF表单设计器(在VS2008上)引发虚假错误。 尽管有错误,应用程序仍会编译并成功运行。 将ImageData
静态资源从流文档移到包含它的高级控件(如RichTextBox或FlowDocumentReader)中即可解决此问题。
经过多次优化后,这是添加嵌入式背景图像的最简单方法。 谢谢@dbc的转换器。
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ns1="MyProject;assembly=MyProject"
xmlns:system="clr-namespace:System;assembly=mscorlib"
>
<FlowDocument.Resources>
<ns1:Base64ImageConverter x:Key="base64ImageConverter" ></ns1:Base64ImageConverter>
<system:String x:Key="backgroundImage">/9j/4AAQSkZJRgABAQAAAQAB...</system:String>
</FlowDocument.Resources>
<FlowDocument.Background>
<ImageBrush>
<ImageBrush.ImageSource>
<Binding Converter="{StaticResource base64ImageConverter}"
Source="{StaticResource backgroundImage}"
Mode="OneWay"></Binding>
</ImageBrush.ImageSource>
</ImageBrush>
</FlowDocument.Background>
<Paragraph>
<Run>Hello World!</Run>
</Paragraph>
</FlowDocument>
这是转换器
using System;
using System.IO;
using System.Windows.Data;
using System.Windows.Media.Imaging;
namespace MyProject
{
public class Base64ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string base64String = value as string;
if (base64String == null)
return null;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = new MemoryStream(System.Convert.FromBase64String(base64String));
bitmapImage.EndInit();
return bitmapImage;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
它仅适用于这两段代码。 是的,您可以将System:String与Mode = OneWay绑定。
根据文档,ImageBrush类是密封的,不能扩展。 文档说,如果ImageBrush无法加载ImageSource,则会调用ImageBrush.ImageFailed事件。 请参阅此处: 文档
您可以像这样在XAML中注册处理程序: <ImageBrush ImageFailed="eventhandler"/>
您的处理程序只需要读取ImageBrush.ImageSource的值,将String解析为BitmapImage对象(如另一个问题中所示),然后设置BitmapImage对象到ImageSource像这样: yourImageBrush.ImageSource=Base64StringToBitmap(ImageBrush.ImageSource.GetValue.ToString())
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.