简体   繁体   中英

How to edit an observableCollection while WPF app is running

I am making a To-do List application for one of my classes. Now I have tried in a console app to update objects (of TaskModels a type I defined) inside an observable collection and it has seemed to work. But now I am trying to update the entries inside the observable collection. I have wrote some code that I thought was going to change the value but it did not change the value in the ListBox I will include the code below for TaskModel.

Originally I was wanting to have the edit button open a new window that allowed the user to input what the wanted the task to be and then they press a button maybe called change task and it sends it back to the original window. But for simpleness at the moment I would like to change with the textbox in the user control in the main window.

I am also pretty new to making apps in WPF so this is all pretty new to me and I am trying to learn it all.

Below is my TaskModel and the only thing it does is get and set the TaskName.

namespace ToDoList.Model
{
public class TaskModel
{
private string taskName;

        public string TaskName {
            get { return taskName; }
            set { taskName = value; }
        }
    
    }

}

I wrote the following code hoping that it would allow me to change the value of the TaskName but it does not seem to be working. Is there anyhting else that I should add to the code for it change the TaskName properly? Any tips or anything that could help me with this problem.

Below is the XAML code for my main window. It is a really simple UI, it features a ListBox which uses an ObservableCollection as its itemsource and when the listbox has a new item put into it has a checkbox to the left of it.

Below I will include the main window XAML and the C# code.

<Window x:Class="ToDoList.DemoMainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ToDoList"
        mc:Ignorable="d"
        Title="The To-Do List" Height="500" Width="500" FontSize="22"
        Background="White">
    <Grid Margin="10" Background="BlueViolet">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
        </Grid.RowDefinitions>

        <StackPanel Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2">
            <TextBlock>Tasks to do:</TextBlock>
            <!-- <TextBlock>Blah blah</TextBlock> -->

            <!-- <local:UCLabelTextBxInput x:Name="TxtUCSaveToFileLocation" Title="Save to File Location" MaxLength="50"></local:UCLabelTextBxInput> -->
            <ListBox x:Name="LstBoxTasks" MinHeight="200" MaxHeight="200" SelectionMode="Multiple">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <CheckBox IsChecked="{Binding Mode=OneWay}" Content="{Binding TaskName, Mode=TwoWay}" FontSize="14"></CheckBox>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <local:UCLabelTextBxInput x:Name="TxtUCEnteredTask" Title="Enter Task Here:" MaxLength="50"></local:UCLabelTextBxInput>
            <Button x:Name="BtnAddTask" Click="BtnAddTask_Click" Background="Chocolate">Add Task to List</Button>
        </StackPanel>

        <Button Grid.Column="0" Grid.Row="1" Margin="0,10,20,0" x:Name="btnDeleteTask" Click="BtnDeleteTask_Click" Background="Chocolate">Delete Task</Button>
        <Button Grid.Column="1" Grid.Row="1" Margin="20,10,0,0" Background="Chocolate" Click="BtnEditTask_Click">Edit Task</Button>
        <Button Grid.Column="0" Grid.Row="2" Margin="0,10,0,10" Grid.ColumnSpan="2" Background="Chocolate" Click="BtnHelp_Click">Help</Button>
    </Grid>
</Window>

Then finally here is the C# code:

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.Model;

namespace ToDoList
{
    /// <summary>
    /// Interaction logic for DemoMainWindow.xaml
    /// </summary>
    public partial class DemoMainWindow : Window
    {
        SaveDataModel saveDataModel = new SaveDataModel();

        ObservableCollection<TaskModel> tasksModels = new ObservableCollection<TaskModel>();
        
        public DemoMainWindow()
        {
            InitializeComponent();

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

           

            LstBoxTasks.ItemsSource = tasksModels;


        }

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

        private void BtnDeleteTask_Click(object sender, RoutedEventArgs e)
        {
            if(LstBoxTasks.SelectedItem != null)
            {
                tasksModels.Remove(LstBoxTasks.SelectedItem as TaskModel);
            }
        }

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

            helpWindow.Show();
        }

        private void BtnEditTask_Click(object sender, RoutedEventArgs e)
        {
            if (LstBoxTasks.SelectedItem != null)
            {
                tasksModels[LstBoxTasks.SelectedIndex].TaskName = TxtUCEnteredTask.txtLimitedInput.Text;
            }
        }
    }
}

Your property TaskName is not calling the OnPropertyChanged() method that notifies your view that the name changed.

You can do something like that:

private string taskName;

public string TaskName {
     get { return taskName; }
     set {
       if( value != taskName) {
         taskName = value;
         OnPropertyChanged("TaskName");
      }
     }
}

protected void OnPropertyChanged(string name) {
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
    handler(this, new PropertyChangedEventArgs(name));
}

}

Remarks:

The best way to do WPF is to do MVVM. You should check out this link: https://www.codeproject.com/Tips/806587/Basic-MVVM-Listbox-Binding-in-WPF

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