65.9K
CodeProject 正在变化。 阅读更多。
Home

ExImage -- 一个非常类似于 Image 控件且支持图像平铺的 Silverlight 控件

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2010年1月24日

Ms-PL

2分钟阅读

viewsIcon

34183

downloadIcon

1052

ExImage 是一个 Silverlight 控件,与内置的 Image 控件非常相似,但它支持三种额外的拉伸模式:RepeatX、RepeatY 和 RepeatXY,这意味着图像可以水平、垂直或同时进行平铺。

Screen Capture

引言

ExImage 是一个 Silverlight 控件,与内置的 Image 控件非常相似,但它支持三种额外的拉伸模式:RepeatXRepeatYRepeatXY。这意味着图像可以水平方向、垂直方向或同时进行平铺。

Repeat in X Direction

图像在 x 方向重复。红色部分是背景。

Repeat in Y Direction

图像在 y 方向重复。红色部分是背景。

Repeat in both X and Y Direction

图像在 x 和 y 方向都重复。

背景

在 HTML 中,图像背景支持 x 方向重复、y 方向重复以及两个方向同时重复。但在 Silverlight 中,Image 控件仅支持 NoneFillUniformUniformFill 拉伸模式。而且,您无法轻易地在 x/y 方向平铺图像。因此,我创建了 ExImage 控件来模拟 HTML 背景图像的行为,并让您轻松使用它。

Using the Code

它在行为和使用方法上都与内在的 Image 控件非常相似。首先,您应该将对 Cokkiy.ExImage 程序集的引用添加到您的 Silverlight 项目中。

然后,在您的页面 XAML 文件中,您可以像使用 Image 控件一样放置它,并设置其 SourceStretch 属性。

<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);
}

在前面的代码中,imgWidthimgHeight 表示图像的实际宽度和高度,可以从 BitmapSource 对象中获取。BitmapSource 类有两个属性,PixelHeightPixelWidth,它们分别表示图像的宽度和高度。但是,这些属性只有在图像加载后才有值,因此您需要处理 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日:最初发布。
© . All rights reserved.