gpt4 book ai didi

wpf - ListBox 中的 TextBox、Button 和 ListBox

转载 作者:行者123 更新时间:2023-12-05 08:44:48 28 4
gpt4 key购买 nike

我有一个列表框,每个列表项中都有一堆控件。

<ListBox x:Name="projectList" IsSynchronizedWithCurrentItem="True">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" />
<ListBox x:Name="taskList" ItemsSource="{Binding Tasks}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBox x:Name="textBoxTask" />
<Button
x:Name="ButtonAddNewTask"
Content="Test"
CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext}"
Click="ButtonAddNewTask_Click"
/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

当我单击列表框中的按钮时,我想向列表框中的列表框添加一个新项目。我已经走到这一步了。所以我的问题是如何获取文本框以及如何更新列表框?

这是我的点击事件

private void ButtonAddNewTask_Click(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
Project proj = button.DataContext as Project;
if(proj.Tasks == null)
proj.Tasks = new List<Task>();

proj.Tasks.Add(new Task("Added Task"));
}

谢谢

最佳答案

最简单的解决方案可能是用一个对象代表外部 ListBox 中的每一项。然后它将具有表示项目中每个控件的属性 - TextBox 中的文本和 ListBox 中的项目(我认为是基于您的 Click 处理程序的任务列表)。

在您的 Click 处理程序中,您可以获得 Button 的 DataContext(它应该是外部列表集合中的一个项目),并将一个新的 Task 添加到该对象的任务列表中。由于内部 ListBox 绑定(bind)到该列表,它应该用新项目更新(假设它在添加项目时发送事件,例如 ObservableCollection)。

更新:根据您的评论,以下内容应该有效。

您的 Project 类应该有两个属性:

class Project
{
public string Name { get; set; }

private ObservableCollection<Task> tasks =
new ObservableCollection<Task>();
public IList<Task> Tasks
{
get { return this.tasks; }
}
}

Task 类只有一个属性 - 任务的名称。

ProjectView 类是 Project 类的包装器(我从@timothymcgrath 的回答中得到这个想法)。它跟踪新任务的名称和当前的 Project:

class ProjectView : INotifyPropertyChanged
{
public Project Project { get; set; }

private string newTaskName = string.Empty;
public string NewTaskName
{
get { return this.newTaskName; }
set
{
this.newTaskName = value;
this.OnPropertyChanged("NewTaskName");
}
}

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
PropertyChangedEventHandler eh = this.PropertyChanged;
if(null != eh)
{
eh(this, new PropertyChangedEventArgs(propName));
}
}
}

您需要一个新类作为DataContext。像这样:

class Model
{
private ObservableCollection<ProjectView> projects =
new ObservableCollection<ProjectView>();
public IList<ProjectView> Projects
{
get { return this.projects; }
}
}

在后面的代码中,将对象的DataContext设置为上述类的实例:

public class Window1
{
public Window1()
{
this.InitializeComponent();

this.DataContext = this.model;
}

private Model model = new Model();
}

在 XAML 中,应修改绑定(bind)以绑定(bind)到上述属性:

<ListBox x:Name="projectList" IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Path=Projects}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Project.Name}" />
<ListBox x:Name="taskList"
ItemsSource="{Binding Project.Tasks}"
DisplayMemberPath="Name" />
<TextBox x:Name="textBoxTask"
Text="{Binding Path=NewTaskName, UpdateSourceTrigger=PropertyChanged}"/>
<Button x:Name="ButtonAddNewTask" Content="Test"
Click="ButtonAddNewTask_Click" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

最后,在按钮的点击处理程序中,创建任务。 ButtonDataContext 将是该项目的 ProjectView

private void ButtonAddNewTask_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button)sender;
ProjectView curProject = btn.DataContext as Project;
if(null != curProject)
{
curProject.Project.Tasks.Add(new Task()
{
Name = curProject.NewTaskName
});
}
}

由于所有控件都通过绑定(bind)获取它们的值,因此您无需访问控件本身来获取数据 - 只需使用已经提供控件的数据结构即可。

将创建任务的代码移动到另一个类(可能是 Project)可能会更好,但我只是将它留在事件处理程序中以便于我输入。

更新 2:修改了上面的代码,将 NewTaskName 属性移动到一个单独的类中,该类包装了一个 Project 的实例,以便与用户界面。这对你更有效吗?

关于wpf - ListBox 中的 TextBox、Button 和 ListBox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/632713/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com