ExImage -- 一个非常类似于 Image 控件且支持图像平铺的 Silverlight 控件
ExImage 是一个 Silverlight 控件,与内置的 Image 控件非常相似,但它支持三种额外的拉伸模式:RepeatX、RepeatY 和 RepeatXY,这意味着图像可以水平、垂直或同时进行平铺。
引言
ExImage 是一个 Silverlight 控件,与内置的 Image
控件非常相似,但它支持三种额外的拉伸模式:RepeatX
、RepeatY
和 RepeatXY
。这意味着图像可以水平方向、垂直方向或同时进行平铺。
背景
在 HTML 中,图像背景支持 x 方向重复、y 方向重复以及两个方向同时重复。但在 Silverlight 中,Image
控件仅支持 None
、Fill
、Uniform
和 UniformFill
拉伸模式。而且,您无法轻易地在 x/y 方向平铺图像。因此,我创建了 ExImage
控件来模拟 HTML 背景图像的行为,并让您轻松使用它。
Using the Code
它在行为和使用方法上都与内在的 Image
控件非常相似。首先,您应该将对 Cokkiy.ExImage
程序集的引用添加到您的 Silverlight 项目中。
然后,在您的页面 XAML 文件中,您可以像使用 Image
控件一样放置它,并设置其 Source
和 Stretch
属性。
<cokkiy:ExImage x:Name="myImage" Source="s.jpg"
Stretch="RepeatX" Background="#FFDA2525" Width="400" Height="300"/>
工作原理
我们都知道,在 Silverlight 中,显示图像的唯一方法是使用 Image
控件,并且没有直接操作图像的方法或函数。因此,平铺图像的唯一方法是使用多个 Image
控件并将它们平铺到目标矩形上。最终结果将类似于图像平铺。
现在,让我们看看 RepeatX
模式是如何实现的。
case ExStretch.RepeatX:
{
int count = (int)Math.Ceiling(Container.ActualWidth / imgWidth);
double totalUsedWidth = 0.0; //Already used Width
double height = Math.Min(imgHeight, Container.ActualHeight);
for (int i = 0; i < count; i++)
{
double remain = Container.ActualWidth - totalUsedWidth;
Image img = new Image();
img.Stretch = System.Windows.Media.Stretch.None;
img.Width = remain >= imgWidth ? imgWidth : remain;
img.Height = height;
img.Source = Source;
Canvas.SetLeft(img, imgWidth * i);
Canvas.SetTop(img, 0);
imagesList.Add(img);
totalUsedWidth += imgWidth;
}
}
break;
在代码中,我们首先计算 count
,即应该在 x 方向放置多少个 Image
控件。然后,我们创建尽可能多的 Image
控件并设置它们的左侧位置。然后,我们将它们保存到一个列表中。
最后,我们将列表中保存的 Image
添加到 Conatiner
,这是一个 Canvas
控件。
foreach (var item in imagesList)
{
Container.Children.Add(item);
}
在前面的代码中,imgWidth
和 imgHeight
表示图像的实际宽度和高度,可以从 BitmapSource
对象中获取。BitmapSource
类有两个属性,PixelHeight
和 PixelWidth
,它们分别表示图像的宽度和高度。但是,这些属性只有在图像加载后才有值,因此您需要处理 ImageOpened
事件来检索这些值。
//Calc image real size
private void CalcImageSize(ImageSource imageSource)
{
if (imageSource != null)
{
Image img = new Image();
img.ImageOpened += new EventHandler<RoutedEventArgs>(img_ImageOpened);
img.Source = imageSource;
Container.Children.Clear();
// If we don't add this image to the visual tree,
// the image will never be loaded
// so, the ImageOpened event will nerver happeded
Container.Children.Add(img);
}
}
void img_ImageOpened(object sender, RoutedEventArgs e)
{
Image img = sender as Image;
imgHeight = (img.Source as BitmapSource).PixelHeight;
imgWidth = (img.Source as BitmapSource).PixelWidth;
Container.Children.Remove(img); // remove this because we no need it
img = null;
CreateImage();
}
有关如何获取图像尺寸的更多信息,您可以阅读这篇 Silverlight 每日技巧 #13 - 如何在 Silverlight 中获取图像的尺寸 以及这些 http://forums.silverlight.net/forums/t/14637.aspx 文章。
历史
- 2010年1月24日:最初发布。