You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Forms:代码中修改ImageSource尺寸并处理空值显示

Solution: Modify Image Size in Code (Not XAML) + Handle Empty Image Logic

Got it, let's break down what's going wrong here and fix your issues step by step.

First, the core problem with your existing size-modification code: ImageSource doesn't control UI element dimensions—that's the job of the Image widget that displays the source. The WidthRequest property belongs to the Image control, not the ImageSource itself, so setting it on the source does nothing for the actual displayed size.

Let's tackle both your requirements:


1. Fix Empty/Unknown Image Display Logic

Instead of returning null when the type is unknown or invalid, return a placeholder image resource. This ensures consistent UI instead of blank space:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    // Clean up type checking with pattern matching
    if (value is TYPE type && type != TYPE.UNKNOWN)
        return GetTypeImageResource(type);
    
    // Return a default placeholder for unknown/invalid types
    return ImageSource.FromResource("Pokedex.Resources.Types.UnknownPlaceholder.png");
}

private ImageSource GetTypeImageResource(TYPE type)
{
    return ImageSource.FromResource($"Pokedex.Resources.Types.{type.ToString()}.png");
}

2. Control Image Size in Code (No XAML)

Since ImageSource can't handle sizing, here are three practical approaches depending on your needs:

Option A: Set Size Directly on the Image Control

If you're creating the Image widget in code (not XAML), just set its WidthRequest and HeightRequest properties directly after binding the source:

// Example: Creating the Image control in code
var typeImage = new Image();

// Bind the source using your converter
typeImage.SetBinding(
    Image.SourceProperty, 
    new Binding("PokemonType", converter: new TypeToImageSourceConverter())
);

// Set fixed size (adjust values as needed)
typeImage.WidthRequest = 48;
typeImage.HeightRequest = 48;

// Add to your layout
yourLayout.Children.Add(typeImage);

Option B: Dynamic Sizing Based on Type (MultiValueConverter)

If you need different sizes for different types, use a IMultiValueConverter to return both the image source and size, then bind both properties to the result:

First, create the multi-converter:

class TypeToImageAndSizeConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Length == 0 || !(values[0] is TYPE type))
            return new { Source = ImageSource.FromResource("Pokedex.Resources.Types.UnknownPlaceholder.png"), Size = 48 };

        if (type == TYPE.UNKNOWN)
            return new { Source = ImageSource.FromResource("Pokedex.Resources.Types.UnknownPlaceholder.png"), Size = 48 };

        // Define size rules per type
        int size = type switch
        {
            TYPE.FIRE or TYPE.WATER => 60,
            TYPE.DRAGON => 64,
            _ => 48
        };

        return new {
            Source = ImageSource.FromResource($"Pokedex.Resources.Types.{type.ToString()}.png"),
            Size = size
        };
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Then use it in code to bind both source and size:

var typeImage = new Image();
var multiBinding = new MultiBinding
{
    Converter = new TypeToImageAndSizeConverter(),
    Bindings = { new Binding("PokemonType") }
};

// Bind source and size properties to the converter's result
typeImage.SetBinding(Image.SourceProperty, new Binding(".Source", Source = multiBinding));
typeImage.SetBinding(Image.WidthRequestProperty, new Binding(".Size", Source = multiBinding));
typeImage.SetBinding(Image.HeightRequestProperty, new Binding(".Size", Source = multiBinding));

Option C: Custom Image Control (Cleanest for Reusable Code)

For a reusable solution, create a custom Image subclass that handles type-to-source and type-to-size logic internally:

public class TypeImage : Image
{
    public static readonly BindableProperty PokemonTypeProperty =
        BindableProperty.Create(
            nameof(PokemonType), 
            typeof(TYPE), 
            typeof(TypeImage), 
            propertyChanged: OnPokemonTypeChanged
        );

    public TYPE PokemonType
    {
        get => (TYPE)GetValue(PokemonTypeProperty);
        set => SetValue(PokemonTypeProperty, value);
    }

    private static void OnPokemonTypeChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var image = bindable as TypeImage;
        if (image == null || !(newValue is TYPE type))
        {
            image.Source = ImageSource.FromResource("Pokedex.Resources.Types.UnknownPlaceholder.png");
            image.WidthRequest = image.HeightRequest = 48;
            return;
        }

        if (type == TYPE.UNKNOWN)
        {
            image.Source = ImageSource.FromResource("Pokedex.Resources.Types.UnknownPlaceholder.png");
            image.WidthRequest = image.HeightRequest = 48;
            return;
        }

        // Set image source
        image.Source = ImageSource.FromResource($"Pokedex.Resources.Types.{type.ToString()}.png");
        
        // Set size based on type
        image.WidthRequest = image.HeightRequest = type switch
        {
            TYPE.FIRE or TYPE.WATER => 60,
            TYPE.DRAGON => 64,
            _ => 48
        };
    }
}

Then use it in code like this:

var typeImage = new TypeImage();
typeImage.SetBinding(TypeImage.PokemonTypeProperty, "PokemonType");
yourLayout.Children.Add(typeImage);

Why Your Original Size Code Failed

To recap:

  • WidthRequest is a property of the Image UI control, not the ImageSource data object
  • ImageSource only provides the image data; it has no control over how the UI displays that data
  • Creating a custom BindableProperty on ImageSource doesn't link to the Image control's sizing logic, so the change never affects the UI

内容的提问来源于stack exchange,提问作者Faithium

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:24:52