.NET MAUI Изображение неправильного размера

У меня возникла проблема, когда я показываю изображение в .NET MAUI, размер изображения всегда больше, чем он есть на самом деле (синяя часть на изображении ниже).

Скриншот

Мой код выглядит следующим образом:

<Grid>
    <ScrollView>
        <VerticalStackLayout>
            <Image Source = "https://cdn-5e5150f5f911c807c41ebdc8.closte.com/wp-content/uploads/IoT-development-kit-article-banner-scaled-900x400.jpg"
                    Aspect = "AspectFit" BackgroundColor = "Blue">
                <Image.Margin>
                    <OnIdiom Phone = "10" Tablet = "20" Desktop = "20"/>
                </Image.Margin>
            </Image>
        </VerticalStackLayout>
    </ScrollView>
</Grid>

Есть ли способ сохранить размер изображения пропорциональным реальному размеру?

О какой ОС идет речь? Кроме того, как вы думаете, это функция "AspectFit"?

H.A.H. 16.02.2023 11:26

Пожалуйста, прочитайте документы на Aspect

Jason 16.02.2023 12:56

Обратите внимание, что проблема здесь в том, что изображению дается больше места по вертикали, чем ему нужно. Это похоже на layout проблему, а не Aspect проблему. Я не понимаю, почему VerticalStackLayout может придать изображению большую высоту, чем необходимо. Предложения для ОП? @copang, это все еще происходит, если удалить ScrollView? (Я понимаю, что вам может понадобиться ScrollView, но это ценный тест для определения причины.)

ToolmakerSteve 16.02.2023 21:33

Вы можете попробовать установить запрос ширины или высоты для изображения.

Liqun Shen-MSFT 17.02.2023 06:22

@ToolmakerSteve, я пытался удалить ScrollView и даже StackLayout, но результат тот же

copang 17.02.2023 09:45

@LiqunShen-MSFT, я стараюсь не задавать ширину и высоту, потому что ищу способ, чтобы представление автоматически вычисляло размер. Раньше я использовал решение здесь social.msdn.microsoft.com/Forums/en-US/…, но оно не работает с .NET MAUI

copang 17.02.2023 09:51
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я внес некоторые изменения:

  1. Я попытался использовать привязку данных способом MVVM.
  2. Я попытался подсчитать соотношение изображений, используя код платформы.

Ниже приведен мой код,

Для MainPage.xaml разница в том, что я использую привязку данных для свойства Source и AspectRatio изображения, которое будет заявлено в MainPageVeiwModel.

<Grid>
    <ScrollView>
        <VerticalStackLayout>                          
            <a:AspectImage Source = "{Binding ImageUrl}"
                     AspectRatio = "{Binding AspectRatio}" Aspect = "AspectFit" BackgroundColor = "Blue">
                <a:AspectImage.Margin>
                    <OnIdiom Phone = "10" Tablet = "20" Desktop = "20"/>
                </a:AspectImage.Margin>
            </a:AspectImage>
        </VerticalStackLayout>
    </ScrollView>
</Grid>

Для пользовательского элемента управления AspectImage разница в том, что я изменил свойство AspectRatio на Bindable, поскольку мы используем привязку для этого свойства. Подробнее Привязываемые свойства.

public class AspectImage : Image
{
    public static readonly BindableProperty AspectRatioProperty = BindableProperty.Create("AspectRatio", typeof(double), typeof(AspectRatioContainer), null);

    public double AspectRatio
    {
        get { return (double)GetValue(AspectRatioProperty); }
        set { SetValue(AspectRatioProperty, value); }
    }

    public AspectImage()
    {
        SizeChanged += HandleSizeChanged;
    }

    private void HandleSizeChanged(object sender, EventArgs e)
    {
        if (this.Width > 0 && AspectRatio > 0)
        {
            var desiredHeightRequest = this.Width * AspectRatio;
            if ((int)desiredHeightRequest != (int)HeightRequest)
            {
                this.HeightRequest = (int)desiredHeightRequest;
                InvalidateMeasure();
            }
        }
    }
}

Для MainPageViewModel мы добавляем свойство AspectRatio и ImageUrl для настраиваемого элемента управления и подсчета AspectRatio.

public class MainPageViewModel
{
    public string ImageUrl { get; set; }
    public double AspectRatio { get; set; }

    public MainPageViewModel()
    {
        ImageUrl = "https://cdn-5e5150f5f911c807c41ebdc8.closte.com/wp-content/uploads/IoT-development-kit-article-banner-scaled-900x400.jpg";

        AspectRatio = CountAspectRatio(ImageUrl);
    }

    private double CountAspectRatio(string imageUrl)
    {
        var service = new GetImageSizeService();
        Size imageSize = service.GetImageSize(imageUrl);
        return imageSize.Height / imageSize.Width;
    }
}

Из приведенного выше кода в MainPageViewModel мы подсчитываем AspectRatio по коду платформы вызова. Если вы не знакомы с ним, я рекомендую сначала этот учебник: Как написать код для конкретной платформы в .NET MAUI.

Чтобы внедрить код платформы в Maui (в Xamarin можно использовать DependencyService):

Во-первых, в папке Project создайте новый разделяемый класс, назовем его GetImageSizeService:

public partial class GetImageSizeService
{
    public partial Size GetImageSize(string file);
}

Затем создайте еще один частичный класс в папке Platforms/iOS, также назовите его GetImageSizeService. Обратите внимание, что пространство имен должно быть таким же, как у файла выше.

public partial class GetImageSizeService
{
    public partial Size GetImageSize(string file)
    {
        NSData data = NSData.FromUrl(NSUrl.FromString(file));

        UIImage image = UIImage.LoadFromData(data);
        return new Size((double)image.Size.Width, (double)image.Size.Height);
    }
}

Затем в MainPageViewModel мы просто вызываем эту службу и считаем AspectRatio.

=========================== Первый пост=============

Добавленная вами ссылка вдохновила меня. И если я правильно понял ваш вопрос, вы можете попробовать следующий код, который сработал для меня:

Создайте пользовательский элемент управления AspectImage, который устанавливает соотношение сторон для ширины и высоты.

public class AspectImage : Image
{
    public double AspectRatio { get; set; }

    public AspectImage()
    {
        SizeChanged += HandleSizeChanged;
    }

    private void HandleSizeChanged(object sender, EventArgs e)
    {
        if (this.Width > 0 && AspectRatio > 0)
        {
            var desiredHeightRequest = this.Width * AspectRatio;           
            if ((int)desiredHeightRequest != (int)HeightRequest)
            {
                this.HeightRequest = (int)desiredHeightRequest;
                InvalidateMeasure();
            }
        }
    }
}

Для xaml используйте AspectImage. Здесь соотношение сторон кажется 4/9 Примерно равно 0,44

<Grid>
    <ScrollView>
        <VerticalStackLayout>                          
            <a:AspectImage Source = "https://cdn-5e5150f5f911c807c41ebdc8.closte.com/wp-content/uploads/IoT-development-kit-article-banner-scaled-900x400.jpg"
                     AspectRatio = "0.44" Aspect = "AspectFit" BackgroundColor = "Blue">
                <a:AspectImage.Margin>
                    <OnIdiom Phone = "10" Tablet = "20" Desktop = "20"/>
                </a:AspectImage.Margin>
            </a:AspectImage>
        </VerticalStackLayout>
    </ScrollView>
</Grid>

Надеюсь, это сработает для вас.

Можно ли запросить у источника изображения его ширину и высоту? Избавится от необходимости вручную устанавливать соотношение сторон.

ToolmakerSteve 17.02.2023 19:03

Он работает именно так, как я ожидал, большое спасибо. И, как сказал @ToolmakerSteve, было бы здорово, если бы он мог сам определять соотношение.

copang 18.02.2023 03:39

Да, можно, но с использованием кода платформы. Я скоро обновлю свой ответ.

Liqun Shen-MSFT 18.02.2023 04:38

@ToolmakerSteve Большое спасибо за ваше предложение. Я не учел этот момент и теперь пытаюсь получить ширину и высоту с помощью кода платформы.

Liqun Shen-MSFT 18.02.2023 05:16

@copang Я обновил свой ответ, чтобы получить ширину и высоту изображения, а затем коэффициент подсчета. Вы могли бы попробовать.

Liqun Shen-MSFT 18.02.2023 05:18

Другие вопросы по теме