4
votes

I have a listbox which has couple of items. When double clicked on each item, the user get option to edit item (text of item). Now once i update the item, my item in listbox doesn't get updated.

alt text

The first window (one which has listbox) is in MainWindow.xaml file and second window is in EditTaskView.xaml(one which let's edit the items text) file.

The code that displays items in lists is:

Main.Windows.cs

public static ObservableCollection TaskList;

    public void GetTask()
    {
        TaskList = new ObservableCollection<Task>
                           {
                               new Task("Task1"),
                               new Task("Task2"),
                               new Task("Task3"),
                               new Task("Task4")
                           };

        lstBxTask.ItemsSource = TaskList;
    }

private void lstBxTask_MouseDoubleClick(object sender, MouseButtonEventArgs e) {

        var selectedTask = (Task)lstBxTask.SelectedItem;
        EditTask.txtBxEditedText.Text = selectedTask.Taskname;
        EditTask.PreviousTaskText = selectedTask.Taskname;  
        EditTask.Visibility = Visibility.Visible;
    } 

The xaml code that displays the list:

<ListBox x:Name="lstBxTask" Style="{StaticResource ListBoxItems}" MouseDoubleClick="lstBxTask_MouseDoubleClick">
        <ListBox.ItemTemplate>              
            <DataTemplate>                   
                <StackPanel>
                    <Rectangle Style="{StaticResource LineBetweenListBox}"/>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Taskname}"  Style="{StaticResource TextInListBox}"/>
                        <Button Name="btnDelete" Style="{StaticResource DeleteButton}" Click="btnDelete_Click"/>                                                     
                    </StackPanel>
                </StackPanel>                   
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox> 
    <ToDoTask:EditTaskView x:Name="EditTask" Grid.Row="1" Grid.RowSpan="2" Grid.ColumnSpan="2" Visibility="Collapsed"/> 

The Save button in TaskEditView.xaml does this:

    public string PreviousTaskText { get; set; }

 private void btnSaveEditedText_Click(object sender, RoutedEventArgs e)
 {
            foreach (var t in MainWindow.TaskList)
            {
                if (t.Taskname == PreviousTaskText)
                {
                    t.Taskname = txtBxEditedText.Text;
                }
           }

            Visibility = Visibility.Collapsed;

 }

TaskList is the ObservableCollection, and i though once you update the value the UI gets refreshed. But doesn't seem to work that way.

What am i missing?

4

4 Answers

2
votes

Looks like you may need to implement INotifyPropertyChanged in your Task class. This interface alerts the UI that underlying data has changed and it needs to repull the data to update the view.

4
votes

It's important to note that although the ObservableCollection class broadcasts information about changes to its elements, it doesn't know or care about changes to the properties of its elements. In other words, it doesn't watch for property change notification on the items within its collection. If you need to know if someone has changed a property of one of the items within the collection, you'll need to ensure that the items in the collection implement the INotifyPropertyChanged interface, and you'll need to manually attach property changed event handlers for those objects

Read this article for more info: http://msdn.microsoft.com/en-us/magazine/dd252944.aspx

To implement PropertyChanged notification check this: http://msdn.microsoft.com/en-us/library/ms743695.aspx

3
votes

Ok here is the working code:

public class Task: INotifyPropertyChanged
    {
        //public string Taskname { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;
        private string _taskname;
        public Task(string value)
        {
            this._taskname = value;
        }
        public string Taskname
        {
            get { return _taskname; }
            set
            {
                _taskname = value;
                OnPropertyChanged("Taskname");
            }
        }
        private void OnPropertyChanged(string value)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(value));
            }
        }
    }
0
votes

all the answers so far are very good,just for education purposes. have you tried to do

listbox.items.Refresh();

after updating?