.Нет MAUI Контентный вид и связуемые свойства

Вопрос или проблема

Я пытаюсь понять, что я делаю не так при создании пользовательского элемента управления .NET MAUI с использованием ContentView. Я много раз читал документацию, но так и не смог добиться ожидаемого поведения. Возможно, я ожидаю неправильный результат. Я пишу этот элемент управления полностью на C# без XAML и использую пакет CommunityToolkit.Maui.Markup для привязки к компоненту. Пользовательский элемент управления определен следующим образом:

public partial class Elevation : ContentView
{
    public static readonly BindableProperty TapCommandProperty = BindableProperty.Create(
           nameof(TapCommand),
           typeof(ICommand),
           typeof(Elevation),
           default(ICommand));

    public ICommand TapCommand
    {
        get => (ICommand)GetValue(TapCommandProperty);
        set => SetValue(TapCommandProperty, value);
    }

    public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(
        nameof(CornerRadius),
        typeof(CornerRadius),
        typeof(Elevation),
        new CornerRadius(5));

    public CornerRadius CornerRadius
    {
        get => (CornerRadius)GetValue(CornerRadiusProperty);
        set => SetValue(CornerRadiusProperty, value);
    }

    new public static readonly BindableProperty ShadowProperty = BindableProperty.Create(
        nameof(Shadow),
        typeof(Shadow),
        typeof(Elevation),
        new Shadow());

    new public Shadow Shadow
    {
        get => (Shadow)GetValue(ShadowProperty);
        set => SetValue(ShadowProperty, value);
    }

    public Elevation()
    {
        Content = new Border()
        {
            Content = Content
        }.Bind(PaddingProperty, nameof(Padding), source: this)
         .Bind(BackgroundColorProperty, nameof(BackgroundColor), source: this)
         .Bind(ShadowProperty, nameof(Shadow), source: this)
         .Bind(Border.StrokeShapeProperty, nameof(CornerRadius), source: this, converter: new CornerRadiusToRoundRectangleConverter());
    }
}

public class CornerRadiusToRoundRectangleConverter : IValueConverter
{

    public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        if (value is CornerRadius cornerRadius)
        {
            return new RoundRectangle { CornerRadius = cornerRadius };
        }
        return new RoundRectangle { CornerRadius = new CornerRadius(5) };
    }

    public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

И вот как я ожидаю использовать его, исходя из того, что я до сих пор прочитал/узнал:

new Elevation()
        {
            Padding = 10,
            TapCommand = action,
            CornerRadius = new CornerRadius(5, 30, 5, 30),
            Content = new Grid()
            {
                Children =
                    {
                        new Grid()
                        {
                            ColumnDefinitions = Columns.Define(25, Star, Star),
                            Children =
                            {
                                icon.IconSize(15).CenterVertical().IconColor(ColorExtensions.FromStaticResource("Primary")).Column(0),
                                new Label()
                                    .Text(actionName)
                                    .Font(size: 18)
                                    .Column(1),
                                new MauiIcon()
                                    .End()
                                    .CenterVertical()
                                    .Icon(FontAwesomeSolidIcons.ChevronRight)
                                    .IconSize(12.5)
                                    .Column(2)
                            }
                        }
                    }
            }
        }.AppThemeColorBinding(
            BackgroundColorProperty,
            ColorExtensions.FromStaticResource("Gray200"),
            ColorExtensions.FromStaticResource("Gray900"));

Свойства Padding и BackgroundColor применяются правильно и видны в пользовательском интерфейсе, но свойства Shadow и StrokeShape не отображаются в пользовательском интерфейсе. Я также не уверен, что правильно использую свойство Content. Есть ли какие-либо мысли, так как у меня больше не осталось идей?

Ответ или решение

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

Проблемы и исправления

  1. Использование свойства Content:
    В вашем конструкторе, когда вы задаете Content для ContentView, вы меняете его на новый экземпляр Border, но затем вы пытаетесь назначить Content внутри этого нового Border, что указывает снова на ContentView. В результате происходит цикл, так как свойство Content ссылается на себя. Вместо этого, вы должны назначить ваш пользовательский контент как содержимое Border.

    Измените конструкцию Content на следующую:

    public Elevation()
    {
       var border = new Border()
       {
           // Устанавливаем здесь для новых контентов, а не на ContentView
           Content = new ContentView() // предполагается, что это будет ваш контент
       };
    
       Content = border;
    
       // Применяем биндинги
       border.Bind(PaddingProperty, nameof(Padding), source: this)
             .Bind(BackgroundColorProperty, nameof(BackgroundColor), source: this)
             .Bind(ShadowProperty, nameof(Shadow), source: this)
             .Bind(Border.StrokeShapeProperty, nameof(CornerRadius), source: this, converter: new CornerRadiusToRoundRectangleConverter());
    }
  2. Применение свойства Shadow:
    Uбедитесь, что ваш тип Shadow правильно реализован и используется в Border. В .NET MAUI свойство Shadow должно поддерживаться корректно, если используется в UI. Проверьте, что ваша версия .NET MAUI актуальна и поддерживает нужные свойства.

  3. Отображение CornerRadius:
    Ваш конвертер CornerRadiusToRoundRectangleConverter выглядит в целом правильно, но убедитесь, что CornerRadius применяется к нужному свойству. В методе Convert проверьте, действительно ли используется RoundRectangle, и что оно правильно работает с Border. Попробуйте временно добавить обработку вывода в Debug, чтобы проверить, возвращается ли нужное значение.

  4. Используйте интерфейс ICommand:
    Убедитесь, что TapCommand реализует интерфейс ICommand и что команда привязывается корректно. Проверьте наличие реализации команды, например, RelayCommand из CommunityToolkit.Mvvm или аналогичной реализации, которая вызывает нужный метод.

Пример использования

Ваш пример использования Elevation может выглядеть следующим образом, однако убедитесь, что изменения, предложенные выше, выполнены:

var action = new Command(() => { /* ваша логика */ });
var elevation = new Elevation()
{
    Padding = 10,
    TapCommand = action,
    CornerRadius = new CornerRadius(5, 30, 5, 30),
    Content = new Grid()
    {
        Children =
        {
            new Grid()
            {
                ColumnDefinitions = Columns.Define(25, Star, Star),
                Children =
                {
                    icon.IconSize(15).CenterVertical().IconColor(ColorExtensions.FromStaticResource("Primary")).Column(0),
                    new Label()
                        .Text(actionName)
                        .Font(size: 18)
                        .Column(1),
                    new MauiIcon()
                        .End()
                        .CenterVertical()
                        .Icon(FontAwesomeSolidIcons.ChevronRight)
                        .IconSize(12.5)
                        .Column(2)
                }
            }
        }
    }
}.AppThemeColorBinding(
    BackgroundColorProperty,
    ColorExtensions.FromStaticResource("Gray200"),
    ColorExtensions.FromStaticResource("Gray900"));

Заключение

Проверьте каждое из предложенных изменений, чтобы убедиться, что свойства Shadow и CornerRadius корректно применяются. Сравните вашу реализацию с примерами, представленными в документации .NET MAUI, чтобы убедиться в правильности подхода.

Если после всех этих изменений проблема все еще существует, возможно, вам стоит рассмотреть возможность тестирования с помощью простых значений для свойств Shadow и CornerRadius, чтобы изолировать проблему.

Оцените материал
Добавить комментарий

Капча загружается...