JokerMartini
JokerMartini

Reputation: 6147

Edit WPF listview item and commit changes

Updated

Link to code: Dropbox files

I have a WPF listview populated with a data which is bound through itemsSource. The item bound is a class object called User which contains a handful of properties such as Name, Age, Mail and Info.

What I want to do is be able to double click any listview item and popup an edit dialog which will allow me to change the Mail and Info of that individual. Those changes however will only be committed when i hit OK otherwise they are ignored.

The problem or place where I'm stuck at is, how do i populate the Edit Dialog with the selected listview item's info/mail? How do i commit those changes back to the item and update the main listview? The rest of the code regarding the popup dialog and whatnot is all implemented already.

The Main Dialog:

enter image description here

XAML - Main Dialog

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="240" Width="350"
        WindowStartupLocation="CenterScreen">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <ListView Name="lvDataBinding" Grid.Row="0" Background="LightBlue">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <WrapPanel>
                        <TextBlock Text="Name: " />
                        <TextBlock Text="{Binding Name}" FontWeight="Bold" />
                        <TextBlock Text=", " />
                        <TextBlock Text="Age: " />
                        <TextBlock Text="{Binding Age}" FontWeight="Bold" />
                        <TextBlock Text=" (" />
                        <TextBlock Text="{Binding Mail}" TextDecorations="Underline" Foreground="Blue" Cursor="Hand" />
                        <TextBlock Text=")" />
                    </WrapPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <EventSetter Event="MouseDoubleClick" Handler="listViewItem_MouseDoubleClick" />
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <Label Content="Selected:" HorizontalAlignment="Left"/>
            <Label Content="{Binding SelectedItem.Info, ElementName=lvDataBinding}" HorizontalAlignment="Left" Width="140"/>
            <!--<Label Content="{Binding ElementName=lvDataBinding, Path=SelectedItem.Name}" HorizontalAlignment="Left" Margin="72,172,0,0" Width="140"/>-->
        </StackPanel>
    </Grid>
</Window>

CS - Main Dialog

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            List<User> items = new List<User>();
            items.Add(new User() { Name = "John Doe", Age = 42, Mail = "[email protected]", Info = "A basketball player"});
            items.Add(new User() { Name = "Jane Doe", Age = 39, Mail = "[email protected]", Info = "A soccer player" });
            items.Add(new User() { Name = "Sammy Doe", Age = 13, Mail = "[email protected]", Info = "A hockey player" });
            lvDataBinding.ItemsSource = items;
        }

        private void listViewItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ListViewItem item = sender as ListViewItem;
            object obj = item.Content;
            //User user = sender as User;
            Console.WriteLine(item);

            // popup window
            Window editDialog = new EditWindow();
            editDialog.Owner = this;
            editDialog.ShowDialog();

            if (editDialog.DialogResult.HasValue && editDialog.DialogResult.Value)
            {
                Console.WriteLine("User pressed OK");
                ;
            }
            else
            {
                Console.WriteLine("User pressed Cancel");
            }

        }
    }

    public class User
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Mail { get; set; }
        public string Info { get; set; }
    }
}

The Edit Dialog:

enter image description here

XAML - Edit Dialog

<Window x:Class="WpfApplication1.EditWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="EditWindow" Height="140" Width="200"
        WindowStartupLocation="CenterScreen">
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Label Content="Email: " Grid.Row="0" Grid.Column="0"/>
        <TextBox Background="AliceBlue" Grid.Row="0" Grid.Column="1" AcceptsReturn="True" TextWrapping="Wrap" DockPanel.Dock="Right"/>
        <Label Content="Info: " Grid.Row="1" Grid.Column="0"/>
        <TextBox Background="AliceBlue" Grid.Row="1" Grid.Column="1" AcceptsReturn="True" TextWrapping="Wrap" DockPanel.Dock="Right"/>
        <StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom">
            <Button Content="Cancel" MinWidth="50" Height="25" Click="ButtonCancelClick"/>
            <Button Content="OK" MinWidth="50" Height="25" Click="ButtonOkClick"/>
        </StackPanel>
    </Grid>
</Window>

CS - Edit Dialog

using System.Windows;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for EditWindow.xaml
    /// </summary>
    public partial class EditWindow : Window
    {
        public EditWindow()
        {
            InitializeComponent();
        }

        private void ButtonOkClick(object sender, RoutedEventArgs e)
        {
            DialogResult = true;
            this.Close();
        }

        private void ButtonCancelClick(object sender, RoutedEventArgs e)
        {
            DialogResult = false;
            this.Close();
        }
    }
}

Upvotes: 0

Views: 2438

Answers (1)

Nikos Tsokos
Nikos Tsokos

Reputation: 3356

There are many things to change in order to get this working.

  1. Implement INotifyPropertyChanged on your User class

You cannot have two way binding in wPF without it. Just google and read till you understand how it works.

  1. Create a public CurrentItem property on your EditWindow

  2. (listViewItem_MouseDoubleClick event)

    • Create a new instance of User class (myUser) and copy all property values from item.Content (you first need to typecast this as a user object)

    • Set the new CurrentItem of editDialog.CurrentItem = myUser

    • if the user presses ok copy all properties of editDialog.CurrentItem back to item.Content object (remember this should be already typecasted to User)

  3. Create all Bindins on EditWindow pointing to CurrentItem object.

Hope that helps.

Upvotes: 1

Related Questions