简体   繁体   中英

How to pass a string from a secondary window to the main window in WPF

I am working on a to-do list application for a project. I would like to change the value of a string in an observableCollection. I am able to change the string in the same window but I would like to change the value from a textbox in a secondary window.

So what I tried to do was is change a string in the first window by using a textbox in the second window. By doing the way I have listed below it just blanks out the item I am trying to edit.

I would like to take the test from the textbox in the second window and use it to modify the taskName in the first window. Below I am going to include my code for the two c# files for the windows.

This is the main window but it is called 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;
            }
        }
    }
}

This is the code for the C# file of the second window:

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

When you create the view, create it's viewmodel before so that you can set the view's datacontext:

    EditWindowViewModel vm = new EditWindowViewModel();
    EditWindow editWindow = new EditWindow()
    {
        DataContext = vm;
    };
    editWindow.Show();
    StringToChange = vm.EditBoxTextProperty; 

Create a bindable property for stroing the editbox's text using INotifyPropertyCganged in the EditWindowViewModel ( see this ):

    private string _editBoxTextProperty;
    public string EditBoxTextProperty
    {
        get => _editBoxTextProperty;
        set 
        {
            if (_editBoxTextProperty != value) 
            {
                _editBoxTextProperty = value;
                OnPropertyChanged();
            }
        }
    }

In the EditWindow xaml, use binding to connect the editbox's text value to your EditBoxTextProperty.

    <TextBox Text="{Binding Path=EditBoxTextProperty}"/>

Usefull links to build a proper WPF application: DataBinding MVVM Pattern

What I have found to be useful when having to interact between elements on different windows is using x:FieldModifier

<TextBox x:Name="textbox" x:FieldModifier="public" />

You can then access the element through the instance of you window

it will appear as WindowInstanceName.textbox

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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