如何在WPF应用程序运行时编辑observableCollection

jum4pzuy  于 2022-11-26  发布在  其他
关注(0)|答案(1)|浏览(235)

我正在为我的一个班级制作待办事项列表应用程序。现在我已经尝试在控制台应用程序中更新对象(我定义的TaskModels类型),它似乎已经工作。但现在我试图更新可观察集合中的条目。我写了一些代码,我认为会改变值,但它没有改变ListBox中的值。我将包括下面的TaskModel代码。
最初我想让编辑按钮打开一个新的窗口,允许用户输入想要的任务,然后他们按下一个按钮,也许叫改变任务,它发送回原来的窗口。但为了简单起见,目前我想改变与文本框中的用户控件在主窗口。
我也是相当新的制作应用程序在WPF所以这一切都是相当新的我,我正试图学习这一切。
下面是我的TaskModel,它所做的唯一事情就是获取和设置TaskName。

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

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

}

我写了下面的代码,希望它能允许我更改TaskName的值,但它似乎不起作用。我是否应该在代码中添加其他内容,以便正确更改TaskName?是否有任何提示或任何可以帮助我解决此问题的内容。
下面是我的主窗口的XAML代码。这是一个非常简单的UI,它有一个使用ObservableCollection作为itemsource的列表框,当列表框中有一个新条目时,它的左边有一个复选框。
下面我将包括主窗口XAML和C#代码。

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

最后是C#代码:

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

js81xvg61#

您的属性TaskName未呼叫通知检视名称已变更的OnPropertyChanged()方法。
你可以这样做:

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

}
备注:
做WPF的最好方法是做MVVM。你应该看看这个链接:https://www.codeproject.com/Tips/806587/Basic-MVVM-Listbox-Binding-in-WPF

相关问题