Передайте привязку в повторно используемый элемент пользовательского интерфейса в MAUI

Я пытаюсь создать повторно используемый ContentView, который можно привязать к конкретному значению экземпляра. Представление определяется следующим образом:

<?xml version = "1.0" encoding = "utf-8" ?>
<ContentView xmlns = "http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:element = "clr-namespace:SimultaneousEquations.Elements"
             x:Class = "SimultaneousEquations.Elements.EquationElement">

    <ContentView.BindingContext>
        <element:EquationElement />
    </ContentView.BindingContext>

    <HorizontalStackLayout HorizontalOptions = "Center">
        <Label FontSize = "22" Text = "{Binding EquationAsString}"  HorizontalOptions = "Center" /> 
        <Label>
            <Label.Margin>8,0,0,0</Label.Margin>
        </Label>
        <Frame 
                WidthRequest = "30" 
                HeightRequest = "30" 
                CornerRadius = "15"
                BorderColor = "Black" 
                Padding = "0" >
            <Label 
                    HorizontalTextAlignment = "Center"
                    VerticalTextAlignment = "Center"
                    Text = "1"
                    TextColor = "Black"
                    FontSize = "22" >
            </Label>
        </Frame>
    </HorizontalStackLayout>
    
</ContentView>

Код позади:

namespace SimultaneousEquations.Elements;

public partial class EquationElement : ContentView
{
    public EquationElement()
    {
        InitializeComponent();
    }

    public string EquationAsString
    {
        get => (string)GetValue(EquationAsStringProperty);
        set => SetValue(EquationAsStringProperty, value);
    }

    public static readonly BindableProperty EquationAsStringProperty =
           BindableProperty.Create(
               nameof(EquationAsString),
               typeof(string),
               typeof(EquationElement),
               "Equation Not Set"//string.Empty
               );
}

Затем я пытаюсь использовать его в ContentPage. Использование повторно используемых элементов приводит к сбою приложения. Использование аналогичного кода непосредственно в представлении отлично работает:

<?xml version = "1.0" encoding = "utf-8" ?>

<ContentPage xmlns = "http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewModels = "clr-namespace:SimultaneousEquations.ViewModels"
             xmlns:elements = "clr-namespace:SimultaneousEquations.Elements"
             x:Class = "SimultaneousEquations.Views.SolveView"
             Title = "Solver">
    <ContentPage.BindingContext>
        <viewModels:SolveViewModel />
    </ContentPage.BindingContext>

    <VerticalStackLayout>

        <!-- THIS CAUSES APP TO CRASH AT LAUNCH -->
        <elements:EquationElement EquationAsString = "{Binding FirstEquation.AsString}"/>

        <!-- THIS WORKS -->
        <HorizontalStackLayout HorizontalOptions = "Center">
            <Label FontSize = "22" Text = "{Binding FirstEquation.AsString}"  HorizontalOptions = "Center" />
            <Label><Label.Margin>8,0,0,0</Label.Margin></Label>
            <Frame 
                WidthRequest = "30" 
                HeightRequest = "30" 
                CornerRadius = "15"
                BorderColor = "Black" 
                Padding = "0" >
                <Label 
                    HorizontalTextAlignment = "Center"
                    VerticalTextAlignment = "Center"
                    Text = "1"
                    TextColor = "Black"
                    FontSize = "22" >
                </Label>
            </Frame>
        </HorizontalStackLayout>

        <Button  HorizontalOptions = "Center"  Text = "Solve" Command = "{Binding SolveCommand}" />

    </VerticalStackLayout>
</ContentPage>

Пожалуйста, помогите мне заставить это работать. Спасибо

Обновлено: На Android приложение просто вылетает без исключения. Я попытался повторно запустить код, который дал сбой в WindowsMachine, и получил исключение в автоматически сгенерированном файле кода с именем Elements_EquationElement.xaml.sg.cs. Исключение попало сюда:

        private void InitializeComponent()
        {
            global::Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml(this, typeof(EquationElement));
        }

В сообщении говорится, что Exception Unhandled - System.StackOverflowException: 'Exception_WasThrown'

Я не уверен, что это кажется очень полезным.

learn.microsoft.com/en-us/dotnet/maui/fundamentals/…

Jason 10.02.2023 20:13

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

ewerspej 10.02.2023 20:42

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

Steve W 10.02.2023 20:58

«У меня нет кода в представлении». Это не сработает. ВСЕГДА должен быть код позади, потому что конструктор представления должен вызывать InitializeComponent();. Начните сначала. Выполните Project/Add Item/ContentVIew, чтобы получить два файла вам нужно. Затем отредактируйте их.

ToolmakerSteve 10.02.2023 23:08

Ну да, у меня есть эта минимальная инициализация. Просто другого кода там нет. Мне нужно иметь возможность указать повторно используемому элементу представления, к какой переменной он должен привязываться вместо жестко запрограммированной привязки, показанной выше.

Steve W 10.02.2023 23:50

@Jason, эта ссылка, которую вы прислали мне выше, выглядит очень многообещающе, но я до сих пор не могу понять, как использовать свойство Bindable в моем повторно используемом элементе представления. Некоторая помощь будет оценена

Steve W 11.02.2023 13:36

см. stackoverflow.com/questions/73691579/…

Jason 11.02.2023 16:31

@Jason Спасибо за это - я переформулировал свой вопрос на основе изменений, которые я внес в связанный вопрос - я думаю, что почти полностью сократил код, который в настоящее время приводит к сбою приложения при запуске. Можете ли вы помочь мне исправить? Спасибо

Steve W 11.02.2023 20:12

Какое исключение вызывает сбой! Какая строка вызывает исключение? Что показывает трассировка стека?

Jason 11.02.2023 20:55

Кажется, это не исключение. Приложение начинает запускаться в эмуляторе Android, а затем просто закрывается. Никаких ошибок/предупреждений от сборки. В выводе 188 строк, но очевидной проблемы нет. Последняя строка: [libc] Фатальный сигнал 11 (SIGSEGV), код 1 (SEGV_MAPERR), адрес ошибки 0x5 в tid 9780 (anousequations), pid 9780 (aneousequations)

Steve W 11.02.2023 21:10

Я попытался повторно запустить его на WindowsMachine и получил странное исключение. напишу в вопросе

Steve W 11.02.2023 21:16

Ваш ContentView рекурсивно привязывается сам к себе

Jason 11.02.2023 21:23

Если я удаляю ContentView.BindingContext из EquationElement, приложение не падает, но значение, которое я пытаюсь связать, также не отображается.

Steve W 11.02.2023 21:41

Попробуйте установить BindingContext = this один конструктор

Jason 11.02.2023 21:52

С BindingContext = this я получаю текст по умолчанию «Equation Not Set».

Steve W 11.02.2023 23:40

пожалуйста, опубликуйте свое полное решение где-нибудь, чтобы я мог его скачать. Отладка этого через бесконечный поток комментариев в утомительном

Jason 12.02.2023 00:36

Я очень ценю помощь Джейсона. Вы можете получить проект из моего дропбокса здесь: dropbox.com/s/uwsmwgd956oi0h9/SimultaneousEquations.7z?dl=0

Steve W 12.02.2023 10:15

Ничего себе - в итоге заработало

Steve W 12.02.2023 14:45
Стоит ли изучать 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
18
93
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Изменение, которое мне нужно было, чтобы заставить эту работу работать, заключалось в том, чтобы изменить способ настройки привязки в многократно используемом ContentView с источником привязки и путем, например так:

    <?xml version = "1.0" encoding = "utf-8" ?>
    <ContentView xmlns = "http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:element = "clr-namespace:SimultaneousEquations.Elements"
             x:Class = "SimultaneousEquations.Elements.EquationElement"
             x:Name = "ControlView">

    <HorizontalStackLayout HorizontalOptions = "Center">
        <Label FontSize = "22" 
               Text = "{Binding Source = {x:Reference ControlView}, Path=EquationAsString}" 
               HorizontalOptions = "Center" /> 
        <Label>
            <Label.Margin>8,0,0,0</Label.Margin>
        </Label>
        <Frame 
                WidthRequest = "30" 
                HeightRequest = "30" 
                CornerRadius = "15"
                BorderColor = "Black" 
                Padding = "0" >
            <Label 
                    HorizontalTextAlignment = "Center"
                    VerticalTextAlignment = "Center"
                    Text = "{Binding Source = {x:Reference ControlView}, Path=EquationNumber}"
                    TextColor = "Black"
                    FontSize = "22" >
            </Label>
        </Frame>
    </HorizontalStackLayout>
    
</ContentView>

Мне очень помог этот пример: Привязка .net Maui имеет несколько уровней глубины

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