单击按钮时如何在另一个列表框中的列表框中插入项目

How to insert items inside listbox withing another listbox on button click

我有一个 Listbox,它绑定到一个 DataTemplate,上面有另一个 Listbox。 在 DataTemplate 上有一个按钮,我想用它来向 DataTemplate ListBox 添加项目,但我找不到执行此操作的解决方案。

这是我的列表框:

<Button Width="200" Content="Add Question" x:Name="btnAddQuestion" Click="btnAddQuestion_Click"/>
<StackPanel Orientation="Horizontal">
     <ListBox Margin="5" x:Name="lvQuestions" ItemTemplate="{StaticResource TemplateQuestionTitle}">
     </ListBox>
</StackPanel>

这是数据模板:

<DataTemplate x:Key="TemplateQuestionTitle">
        <StackPanel Orientation="Vertical">
            <StackPanel Orientation="Horizontal">
                <TextBox  materialDesign:HintAssist.Hint="Enter question" MinWidth="200" Style="{StaticResource MaterialDesignFloatingHintTextBox}"/>
                <Button Content="+" Command="{Binding Source={x:Reference ThisPage},Path=DataContext.Command}" />
            </StackPanel>
            <ListBox ItemsSource="{Binding MyItems}" MinHeight="50">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBox>
                        </TextBox>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </StackPanel>
    </DataTemplate>

这是我页面上的隐藏代码:

public partial class UIBuilder:Window
{
    private CommandVm _commandVm;     
        public UIBuilder()
        {
            InitializeComponent();      
           _commandVm = new CommandVm();
            DataContext = _commandVm;            
        }
        private void btnAddQuestion_Click(object sender, RoutedEventArgs e)
        {
            lvQuestions.Items.Add(null);
        }
}

我已经在我的 ViewModel 上实现了这段代码,以便将项目添加到数据模板列表框:

 public class CommandVm
{
    public ObservableCollection<TextBox> MyItems { get; set; }
    public CommandVm()
    {       
        MyItems = new ObservableCollection<TextBox>();
        Command = new RelayCommand<TextBox>(Execute);
    }

    private void Execute(TextBox textBox)      
    {          
        MyItems .Add(textBox);  
    }

    public ICommand Command { get; set; }
}

我曾经在按钮“+”单击命令上捕获 Execute() 函数,但我的代码没有添加任何列表框项目。

MyItems 是父视图模型的 属性,这意味着您应该像这样绑定到它:

<ListBox ItemsSource="{Binding DataContext.MyItems,
     RelativeSource={RelativeSource AncestorType=Window}}" MinHeight="50">

这也意味着您对所有问题都使用一个项目集合。除了这个明显的设计缺陷外,视图模型不应包含任何 TextBox 元素。这基本上打破了 MVVM 模式的全部内容。

要使此示例符合 MVVM,您应该做的是创建一个 Question class,其中包含项目集合,例如:

public class Question
{
    public Question()
    {
        AddAnswerCommand = new RelayCommand<object>(Execute);
    }

    private void Execute(object obj)
    {
        Items.Add(new Answer());
    }

    public ObservableCollection<Answer> Items { get; }
        = new ObservableCollection<Answer>();

    public ICommand AddAnswerCommand { get; }
}

public class Answer { }

window 的视图模型应该有一个问题集合:

public class CommandVm
{
    public CommandVm()
    {
        AddQuestionCommand = new RelayCommand<object>(Execute);
    }

    public ObservableCollection<Question> Questions { get; }
        = new ObservableCollection<Question>();

    public ICommand AddQuestionCommand { get; }

    private void Execute(object obj)
    {
        Questions.Add(new Question());
    }
}

视图和绑定可以这样定义:

<Window.Resources>
    <DataTemplate x:Key="TemplateQuestionTitle">
        <StackPanel Orientation="Vertical">
            <StackPanel Orientation="Horizontal">
                <TextBox  MinWidth="200" />
                <Button Content="+" Command="{Binding AddAnswerCommand}" />
            </StackPanel>
            <ListBox ItemsSource="{Binding Items}" MinHeight="50">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBox />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </StackPanel>
    </DataTemplate>
</Window.Resources>
<StackPanel>
    <Button Width="200" Content="Add Question" Command="{Binding AddQuestionCommand}"/>
    <ListBox Margin="5"
                 ItemsSource="{Binding Questions}"
                 ItemTemplate="{StaticResource TemplateQuestionTitle}" />
</StackPanel>

此设置允许您向每个单独的问题添加单独的元素。