You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF中如何从次级窗口向主窗口传值修改待办任务名称

待办列表跨窗口编辑TaskName为空值问题

开发待办列表项目时,希望通过次级窗口(EditWindow)的TextBox修改主窗口(DemoMainWindow)ObservableCollection中的TaskName字符串值。同一窗口内修改可正常生效,但从次级窗口操作时,目标编辑项会变为空值。

主窗口(DemoMainWindow)代码

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using ToDoList.ViewModels;
using ToDoList.Model;

namespace ToDoList
{
    /// <summary>
    /// Interaction logic for DemoMainWindow.xaml
    /// </summary>
    public partial class DemoMainWindow : Window
    {
        private ViewModel _viewModel;

        public string? EditedTaskName { get; set; }

        public DemoMainWindow()
        {
            InitializeComponent();

            TxtUCEnteredTask.txtLimitedInput.Text = "Do the dishes";

            _viewModel = new ViewModel();

            DataContext = _viewModel;
        }

        private void BtnAddTask_Click(object sender, RoutedEventArgs e)
        {
            _viewModel.Tasks.Add(new TaskModel() { TaskName = TxtUCEnteredTask.txtLimitedInput.Text });
        }

        private void BtnDeleteTask_Click(object sender, RoutedEventArgs e)
        {
            if(LstBoxTasks.SelectedItem != null)
            {
#pragma warning disable CS8604 // Possible null reference argument.
                _ = _viewModel.Tasks.Remove(item: LstBoxTasks.SelectedItem as TaskModel);
#pragma warning restore CS8604 // Possible null reference argument.
            }
        }

        private void BtnHelp_Click(object sender, RoutedEventArgs e)
        {
            HelpWindow helpWindow = new HelpWindow();
            helpWindow.Show();
        }

        private string? GetEditedTaskName()
        {
            return EditedTaskName;
        }

        private void BtnEditTask_Click(object sender, RoutedEventArgs e)
        {
            if (LstBoxTasks.SelectedItem != null)
            {
                EditWindow editWindow = new EditWindow();
                editWindow.Show();
               //_viewModel.Tasks[LstBoxTasks.SelectedIndex].TaskName = editedTaskName;
            }
        }
    }
}

次级窗口(EditWindow)代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace ToDoList
{
    /// <summary>
    /// Interaction logic for EditWindow.xaml
    /// </summary>
    public partial class EditWindow : Window
    {
        public EditWindow()
        {
            InitializeComponent();
            var DemoMainWindow = this.DataContext;
        }

        private void BtnEdit_Click(object sender, RoutedEventArgs e)
        {
            ((DemoMainWindow)Application.Current.MainWindow).EditedTaskName = EditTextBox.Text;

            // _viewModel.Tasks[LstBoxTasks.SelectedIndex].TaskName = TxtUCEnteredTask.txtLimitedInput.Text;
        }
    }
}

问题原因及解决方案

问题根源

当前代码仅把输入的文本赋值给主窗口的EditedTaskName属性,但没有将这个值同步到ObservableCollection中选中的TaskModel对象;同时,次级窗口没有获取到主窗口中选中的任务项,也没有在编辑完成后触发主窗口更新任务名称的逻辑。

解决方案1:直接传递选中的TaskModel对象

修改主窗口的BtnEditTask_Click方法,将选中的任务项传递给EditWindow:

private void BtnEditTask_Click(object sender, RoutedEventArgs e)
{
    if (LstBoxTasks.SelectedItem is TaskModel selectedTask)
    {
        EditWindow editWindow = new EditWindow(selectedTask);
        editWindow.ShowDialog();
    }
}

修改EditWindow的构造函数,接收并绑定选中的TaskModel:

private readonly TaskModel _selectedTask;

public EditWindow(TaskModel selectedTask)
{
    InitializeComponent();
    _selectedTask = selectedTask;
    EditTextBox.Text = selectedTask.TaskName;
}

private void BtnEdit_Click(object sender, RoutedEventArgs e)
{
    _selectedTask.TaskName = EditTextBox.Text;
    Close();
}

解决方案2:共享ViewModel

让EditWindow直接绑定到主窗口的ViewModel,并传递选中任务的索引:

主窗口打开EditWindow时传递参数:

private void BtnEditTask_Click(object sender, RoutedEventArgs e)
{
    if (LstBoxTasks.SelectedIndex != -1)
    {
        EditWindow editWindow = new EditWindow(_viewModel, LstBoxTasks.SelectedIndex);
        editWindow.ShowDialog();
    }
}

EditWindow接收ViewModel和索引:

private readonly ViewModel _viewModel;
private readonly int _selectedIndex;

public EditWindow(ViewModel viewModel, int selectedIndex)
{
    InitializeComponent();
    _viewModel = viewModel;
    _selectedIndex = selectedIndex;
    EditTextBox.Text = _viewModel.Tasks[selectedIndex].TaskName;
}

private void BtnEdit_Click(object sender, RoutedEventArgs e)
{
    _viewModel.Tasks[_selectedIndex].TaskName = EditTextBox.Text;
    Close();
}

关键注意事项

确保TaskModel实现INotifyPropertyChanged接口,这样修改TaskName时UI才会自动更新:

public class TaskModel : INotifyPropertyChanged
{
    private string _taskName;
    public string TaskName
    {
        get => _taskName;
        set
        {
            _taskName = value;
            OnPropertyChanged(nameof(TaskName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

内容的提问来源于stack exchange,提问作者Savage's Project

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 16:50:30