TextBox, Button, and ListBox in ListBox

I have a list with a bunch of outlines in each element of the list.

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

When I click the button in the list, I want to add a new item to the list in the list. I have come this far. So my question is: how can I get the text box and how to update the list?

Here is my click event

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

Thanx

+1
source share
3 answers

This solution worked for the task at hand, so to speak.

    private void ButtonAddNewTask_Click(object sender, RoutedEventArgs e)
    {
        Button button = (Button)sender;
        DependencyObject obj = LogicalTreeHelper.GetParent(button);
        StackPanel item = obj as StackPanel;
        TextBox textBox = item.FindName("textBoxTask") as TextBox;
        ListBox listBox = item.FindName("taskList") as ListBox;

        Project proj = button.DataContext as Project;
        if(proj.Tasks == null)
            proj.Tasks = new List<Task>();

        listBox.ItemsSource = proj.Tasks;
        listBox.Items.Refresh();
    }
0
source

, , , ListBox. , - TextBox ListBox ( , , Click).

Click Button DataContext ( ) . ListBox , ( , , , , 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 :

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

, . DataContext Button 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
        });
    }
}

, - , .

, , (, Project), .

2. , NewTaskName , Project . ?

+7

I assume your ListBox project is populated with Collection of Project objects. I would add AddNewTask ICommand to the Project class and set it through a property. Then bind the Add New Task button to the new ICommand AddNewTask. For CommandParameter, enter the value of TaskName and it will be passed to the command.

Try reading some MVVMs (Model View ViewModel) for some examples of how this works. It is very clean and works great.

+2
source

Source: https://habr.com/ru/post/1733962/


All Articles