0

如何使用 XAML 样式表中的位置从图像中访问图标

就像我有下图一样,我想访问 2 行和 2 列的图标

通过使用 XAML 样式表任何想法。

http://www.evohosting.co.uk/blog/wp-content/uploads/2011/07/blue.jpg

谢谢

4

1 回答 1

0

该图像并不完全有利于被分割(一些阴影与下面的图标重叠),但如果你想这样做,你可以:

  1. 创建一个类,该类具有从给定行和列的图标表返回图标的方法
  2. 创建一个调用该方法的转换器并将其Source用作Image.

此类获取源图像以及每个图标的宽度和高度。给定行和列索引,该GetIcon函数计算图标的 X 和 Y 位置并返回CroppedBitmap包含图标的 a。您要求的图标已缓存,因此您最终不会多次创建相同的图标。

public class IconSheet
{
    public BitmapImage SheetSource;

    private int iconWidth, iconHeight;

    private Dictionary<Tuple<int, int>, CroppedBitmap> cache =
                    new Dictionary<Tuple<int, int>, CroppedBitmap>();

    public IconSheet( BitmapImage sheetSource, int iconWidth, int iconHeight )
    {
        SheetSource = sheetSource;
        this.iconWidth = iconWidth;
        this.iconHeight = iconHeight;
    }

    public BitmapSource GetIcon( int row, int column )
    {
        var key = Tuple.Create( row, column );
        if( !cache.ContainsKey( key ) )
        {
            cache.Add( key, new CroppedBitmap( SheetSource, new Int32Rect(
                    column * iconWidth, row * iconHeight, iconWidth, iconHeight ) ) );
        }
        return cache[key];
    }
}

接下来我们创建一个IValueConverterIconSheet为值并将行和列作为其参数(格式化为字符串"row,col")。GetIcon它使用返回的行和列调用方法,BitmapSource我们可以将其用作Source我们的Image.

[ValueConversion( typeof( BitmapImage ), typeof( BitmapSource ) )]
public class IconSheetIndexer : IValueConverter
{
    public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
    {
        var iconSheet = (value as IconSheet);
        var coords = (parameter as String).Split( ',' ).Select( s => int.Parse( s.Trim() ) ).ToList();
        return iconSheet.GetIcon( coords[0], coords[1] );
    }

    public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
    {
        return null;
    }
}

在 XAML 中,我们将定义构造函数采用的三个参数 - 图标表作为 aBitmapImage以及每个图标的宽度和高度。我们还将转换器定义为资源。

<Window.Resources>
    <BitmapImage x:Key="iconSheetSource" UriSource="blue.jpg" />
    <sys:Int32 x:Key="iconWidth">95</sys:Int32>
    <sys:Int32 x:Key="iconHeight">95</sys:Int32>
    <local:IconSheetIndexer x:Key="iconSheetIndexer"/>
</Window.Resources>

在代码隐藏中,使用我们在 XAML 资源中定义的参数创建 IconSheet:

public partial class MainWindow : Window
{
    public IconSheet IconSheet { get; private set; }
    public MainWindow()
    {
        InitializeComponent();

        IconSheet = new IconSheet( this.FindResource( "iconSheetSource" ) as BitmapImage,
            (int)this.FindResource( "iconWidth" ),
            (int)this.FindResource( "iconHeight" ) );

        this.DataContext = this;
    }
}

然后,如果您想使用例如第 1 行第 3 列的图标:

<Image Source="{Binding IconSheet, Converter={StaticResource iconSheetIndexer}, ConverterParameter='1,3'}" Stretch="None"/>

结果(UniformGrid与绑定到 的 16 个图标中的每一个一样Image):

示例应用

于 2013-08-26T15:21:11.243 回答