【IT168技术文档】
从assembly中提取图片并显示在UI上的方法是主要LoadImagesFromAssembly.
private void LoadImagesFromAssembly( string assemblyPath )
{
// Try to load the assembly at the specified location.
Assembly assembly = this.LoadAssembly( assemblyPath, true );
if( assembly == null )
return;
this.currentAssembly = assembly;
// Dispose of the images currently being displayed, if any.
if( this.bindingSource.DataSource != null )
foreach( ImageInfo imgInfo in this.bindingSource.DataSource
as List<ImageInfo> )
imgInfo.Dispose();
// Bind to a list of every image embedded in the assembly.
this.bindingSource.DataSource =
this.ExtractImagesFromAssembly( this.currentAssembly );
}
如上, ImageGrabberForm 用BindingSource组件存储图片供数据绑定. BindingNavigator, DataGridView, PropertyGrid 和PictureBox都绑定到这一数据源,就可以相当简单地在各UI元素间保持一致.
从assembly中提取图片的实际工作是在ExtractImagesFromAssembly 方法中:
private List<ImageInfo> ExtractImagesFromAssembly( Assembly assembly )
{
List<ImageInfo> imageInfos = new List<ImageInfo>();
foreach( string name in assembly.GetManifestResourceNames() )
{
using( Stream stream = assembly.GetManifestResourceStream( name ) )
{
// Treat the resource as an icon.
try
{
Icon icon = new Icon( stream );
imageInfos.Add( new ImageInfo( icon, name ) );
continue;
}
catch( ArgumentException )
{
stream.Position = 0;
}
// Treat the resource as a cursor.
try
{
Cursor cursor = new Cursor( stream );
imageInfos.Add( new ImageInfo( cursor, name ) );
continue;
}
catch( ArgumentException )
{
stream.Position = 0;
}
// Treat the resource as an image.
try
{
Image image = Image.FromStream( stream );
// If the image is an animated GIF, do not add it to the
// collection because the Image class cannot handle them and
// will throw an exception when the image is displayed.
FrameDimension frameDim =
new FrameDimension( image.FrameDimensionsList[0] );
bool isAnimatedGif = image.GetFrameCount( frameDim ) > 1;
if( !isAnimatedGif )
imageInfos.Add( new ImageInfo( image, name ) );
else
image.Dispose();
continue;
}
catch( ArgumentException )
{
stream.Position = 0;
}
// Treat the resource as a resource file.
try
{
// The embedded resource in the stream is not an image, so
// read it into a ResourceReader and extract the values
// from there.
using( IResourceReader reader = new ResourceReader( stream ) )
{
foreach( DictionaryEntry entry in reader )
{
if( entry.Value is Icon )
{
imageInfos.Add( new ImageInfo( entry.Value, name ) );
}
else if( entry.Value is Image )
{
imageInfos.Add( new ImageInfo( entry.Value, name ) );
}
else if( entry.Value is ImageListStreamer )
{
// Load an ImageList with the ImageListStreamer and
// store a reference to every image it contains.
using( ImageList imageList = new ImageList() )
{
imageList.ImageStream =
entry.Value as ImageListStreamer;
foreach( Image image in imageList.Images )
imageInfos.Add( new ImageInfo( image, name ) );
}
}
}
}
}
catch( Exception )
{
}
}
}
return imageInfos;
}
上面的代码在assembly中为每个已命名资源都打开一个流,然后依次尝试从流中创建图标Icon, (失败的话创建)光标Cursor, (失败的话创建)图片Image, 全部失败的话通过System.Resources.ResourceReader读取内容. 这个resource reader可以把图片,图标和ImageList中的图片从资源文件.resx中提取出来. ImageInfo类是用来存取图片及其辅助信息的.