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



我有一个Listbox,它绑定到另一个有ListboxDataTemplate。在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:

<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上实现了这段代码,以便将项目添加到数据模板ListBox:

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

我用以捕捉按钮"上的CCD_ 4功能+"click命令,但我的代码没有添加任何ListBox项。

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

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

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

要使此示例符合MVVM,您应该创建一个具有项目集合的Question类,例如:

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

窗口的视图模型应该有一组问题:

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>

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

最新更新