Есть ли способ создать рекурсивный пользовательский элемент управления UWP? - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть класс, который имеет собственную ObservableCollection, встроенную в класс.

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

Ошибка не слишком значительна: сбой синтаксического анализа XAML. E_RUNTIME_SETVALUE [Строка: 91 Позиция: 58] (это строка с рекурсивным вызовом пользовательского элемента управления)

Класс выглядит примерно так (он был сокращен в целях иллюстрации)

    public class BookChapterVm : IBookChapterVm
    {
    public int Id {get;set;}
    public string ChapterText {get;set;}
    public ObservableCollection<IBookChapterVm> Chapters { get; set; } = new ObservableCollection<IBookChapterVm>();
    }

Пользовательский элемент управления выглядит примерно так (опять же, ненужные части удаляются)

<UserControl
    x:Class="Cgs.Ux.UserControls.HelpTextEditor.BookChapterEditorCtrl">
            <ListView
                ItemsSource="{x:Bind Vm.Chapters, Mode=OneWay}">
                <ListView.ItemTemplate>
                    <DataTemplate x:DataType="help:BookChapterVm">
                        <StackPanel Orientation="Horizontal">
                            <local:BookChapterEditorCtrl Vm="{Binding}"/>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
</UserControl>

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

1 Ответ

1 голос
/ 17 апреля 2020

Вот рабочий пример:

На вашей странице:

<local:RecursiveContainer ViewModel="{Binding}" />

Код:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = BuildBookChapterVM();
    }

    private BookChapterVM BuildBookChapterVM()
    {
        BookChapterVM vm1 = new BookChapterVM { ChapterText = "1" };
        BookChapterVM vm21 = new BookChapterVM { ChapterText = "21" };
        BookChapterVM vm22 = new BookChapterVM { ChapterText = "22" };
        BookChapterVM vm211 = new BookChapterVM { ChapterText = "211" };
        vm1.Chapters.Add(vm21);
        vm1.Chapters.Add(vm22);
        vm21.Chapters.Add(vm211);
        return vm1;
    }
}

public class BookChapterVM
{
    public int Id { get; set; }
    public string ChapterText { get; set; }
    public ObservableCollection<BookChapterVM> Chapters { get; set; } = new ObservableCollection<BookChapterVM>();
}

UserControl XAML:

<UserControl
    x:Class="WpfApp2.RecursiveContainer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfApp2"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">
    <StackPanel>
        <TextBlock Text="{Binding ChapterText}" />
        <ItemsControl HorizontalContentAlignment="Stretch" ItemsSource="{Binding Chapters, Mode=OneWay}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <local:RecursiveContainer
                        Margin="10,5,0,5"
                        HorizontalAlignment="Stretch"
                        ViewModel="{Binding}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
</UserControl>

Код U C:

public partial class RecursiveContainer : UserControl
{
    public RecursiveContainer()
    {
        InitializeComponent();
    }

    public BookChapterVM ViewModel
    {
        get { return (BookChapterVM)GetValue(ViewModelProperty); }
        set { SetValue(ViewModelProperty, value); }
    }

    public static readonly DependencyProperty ViewModelProperty =
        DependencyProperty.Register("ViewModel", typeof(RecursiveContainer), typeof(RecursiveContainer));
}

См. Изображение в качестве доказательства концепции. Я надеюсь, что это поможет вам;)

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...