简体   繁体   English

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

[英]How to insert items inside listbox withing another listbox on button click

I have a Listbox which is bound to a DataTemplate that has another Listbox on it.我有一个Listbox ,它绑定到一个DataTemplate上有另一个Listbox On DataTemplate there is a button that I want to use for adding items to DataTemplate ListBox, but I can't find a solution to do this.在 DataTemplate 上有一个按钮,我想用它来将项目添加到 DataTemplate ListBox,但我找不到执行此操作的解决方案。

Here is my 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>

And this is DataTemplate:这是数据模板:

<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>

This is code behind on my page:这是我页面上的代码:

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);
        }
}

I have implemented this code on my ViewModel in order to add items to datatemplate ListBox:我已经在我的 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; }
}

I use to catch the Execute() function on button "+" click command, but my code doesn't add any ListBox item.我曾经在按钮“+”单击命令上捕获Execute() function,但我的代码没有添加任何 ListBox 项目。

MyItems is a property of the parent view model which means that you should bind to it like this: MyItems是父视图 model 的属性,这意味着您应该像这样绑定到它:

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

This also means that you are using one single collection of items for all questions.这也意味着您对所有问题都使用一个项目集合。 Besides this obvious design flaw, a view model should not contain any TextBox elements.除了这个明显的设计缺陷外,视图 model 不应包含任何TextBox元素。 This basically breaks what the MVVM pattern is all about.这基本上打破了 MVVM 模式的全部内容。

What you should do to make this example MVVM compliant is to create a Question class that has a collection of items, eg:要使此示例符合 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 { }

The window's view model should then have a collection of questions:窗口的视图 model 应该有一系列问题:

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());
    }
}

The view and the bindings could then be defined like this:然后可以像这样定义视图和绑定:

<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>

This setup lets you add individual elements to each separate question.此设置允许您向每个单独的问题添加单独的元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM