locked
How to delete a row in a ListView with a DELETE button in each row? RRS feed

  • Question

  • I got a ListView and I need to show a DELETE button on each row in the last column and if I click that button then the row should get deleted.

     So I got a Data Template for that button.

     <DataTemplate x:Key="DeleteButtonTemplate">
                    <Button x:Name="btnDelete" HorizontalAlignment="Left" VerticalAlignment="Top" DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type ListViewItem}}}"  Click="btnDelete_Click" >
                        <StackPanel Orientation="Horizontal">
                            <Image Source="/Images/delete.png" Width="6" Margin="5"/>
                        </StackPanel>
                    </Button>
     </DataTemplate>

     
    Now how I can delete that row in the click event of the button.

      private void btnDelete_Click(object sender, RoutedEventArgs e)
            {
                object item = ((sender as Button).DataContext) as ListViewItem;
             

            }
    Any help would be appreciated.

    Thanks,
    Vidzai.

    Saturday, February 21, 2009 1:43 AM

Answers

  • You can save the index  of the row need to be deleted in the Tag of button.
    When the button is clicked, retrieve the index by the tag of button.
    And then remove it from the data source.
    Re bind the data source to listview at last.

    I build a demo project to show this approach:
    XAML
    <Window x:Class="_temple.Window1" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            xmlns:local="clr-namespace:_temple" 
            Loaded="Window_Loaded" 
        Title="Window1" Height="300" Width="600"
          
     
        <Grid> 
            <ListView x:Name="MyListView"  Margin="0,65,12,0"
                <ListView.View> 
                    <GridView  AllowsColumnReorder="true" 
                        ColumnHeaderToolTip="Employee Information"
                  
                        <GridViewColumn   
                             
                            
                                Header="First Name" Width="100"
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
                                    
                                        <StackPanel Width="100" > 
                                            <TextBlock Text="{Binding FirstName}"/> 
                                        </StackPanel> 
                                   
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
     
                        </GridViewColumn> 
                        <GridViewColumn  
                                Header="Last Name" Width="100"
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
                                     
                                        <StackPanel Width="100" > 
                                            <TextBlock Text="{Binding LastName}"/> 
                                        </StackPanel> 
                              
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
                        </GridViewColumn> 
                        <GridViewColumn  
                                Header="Employee No." Width="100"
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
                                     
                                        <StackPanel Width="100"  > 
                                            <TextBlock Text="{Binding EmployeeNumber}"/> 
                                        </StackPanel> 
                                  
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
                        </GridViewColumn> 
                        <GridViewColumn  x:Name="gridClm_SelectRow" Width="50"
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
     
                                    <Button x:Name="btnDelete"  
                                             Tag="{Binding Index}" 
                                                HorizontalAlignment="Left"  
                                                VerticalAlignment="Top"  
                                                 Click="btnDelete_Click" > 
                                        delete 
                                    </Button> 
     
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
     
                        </GridViewColumn> 
                    </GridView> 
                </ListView.View> 
            </ListView> 
      
        </Grid> 
    </Window> 
     

    C#:
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    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.Navigation; 
    using System.Windows.Shapes; 
    using System.ComponentModel; 
    using System.Collections.ObjectModel; 
     
    namespace _temple 
        /// <summary> 
        /// Interaction logic for Window1.xaml 
        /// </summary> 
        public partial class Window1 : Window 
        { 
            ObservableCollection<EmployeeInfo> list = new ObservableCollection<EmployeeInfo>(); 
            public Window1() 
            { 
                list.Add(new EmployeeInfo("Jesper", "Aaberg", "12345")); 
                list.Add(new EmployeeInfo("Dominik", "Paiha", "98765")); 
                list.Add(new EmployeeInfo("Yale", "Li", "23875")); 
                list.Add(new EmployeeInfo("Muru", "Subramani", "49392")); 
                SetOrder(list); 
     
                InitializeComponent(); 
         
            } 
     
            public void SetOrder(  ObservableCollection<EmployeeInfo> data ) 
            { 
                for (int i = 0; i < data.Count; i++) 
                { 
                    EmployeeInfo ei = (EmployeeInfo)data[i]; 
                    ei.Index = i.ToString(); 
                } 
            } 
     
            private void btnDelete_Click(object sender, RoutedEventArgs e) 
            { 
                Button btn = (Button)sender; 
                int index = int.Parse(btn.Tag.ToString()); 
                list.RemoveAt(index); 
                SetOrder(list); 
                MyListView.ItemsSource = null
                MyListView.ItemsSource = list
            } 
     
            private void Window_Loaded(object sender, RoutedEventArgs e) 
            { 
                MyListView.ItemsSource = list
            } 
        } 
     
        public class EmployeeInfo 
        { 
            private string _firstName; 
            private string _lastName; 
            private string _employeeNumber; 
            public string FirstName 
            { 
                get { return _firstName; } 
                set { _firstName = value; } 
            } 
     
            public string LastName 
            { 
                get { return _lastName; } 
                set { _lastName = value; } 
            } 
     
            public string EmployeeNumber 
            { 
                get { return _employeeNumber; } 
                set { _employeeNumber = value; } 
            } 
     
            public string Index { set; get;  } 
       
     
            public EmployeeInfo(  string firstname, string lastname, string empnumber) 
            {  
                _firstName = firstname
                _lastName = lastname
                _employeeNumber = empnumber
            } 
     
             
        } 
       
     

    Hope it helps.

    ----------------------------------------------------------

    Please mark this thread as answer if you think it is helpful.

    Thank you!

    • Proposed as answer by Tao Liang Monday, February 23, 2009 10:01 AM
    • Marked as answer by Tao Liang Wednesday, February 25, 2009 3:53 AM
    Monday, February 23, 2009 10:01 AM
  • Hi liangtom,

    your answer works fine, but I think we should keep unittesting in mind? I prefere the MVVM approach, so I have taken your sample to show how I would do it.

    As you can see the Window1 codebehind is gone. No click event handler and no index is needed.

    What do you think about my solution?

    XAML:
    <Window x:Class="DummyProject.Window1" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
        xmlns:local="clr-namespace:DummyProject"          
        Title="Window1" Height="300" Width="600">  
          
        <Grid> 
            <ListView Margin="0,65,12,0" ItemsSource="{Binding EmployeeInfos}">  
                <ListView.View> 
                    <GridView  AllowsColumnReorder="true"    
                        ColumnHeaderToolTip="Employee Information">  
     
                        <GridViewColumn  Header="First Name" Width="100">  
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate>                            
                                        <TextBlock Text="{Binding FirstName}"/>                               
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
                        </GridViewColumn> 
                          
                        <GridViewColumn Header="Last Name" Width="100">  
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
                                        <TextBlock Text="{Binding LastName}"/>  
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
                        </GridViewColumn> 
                          
                        <GridViewColumn  Header="Employee No." Width="100">  
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
                                        <TextBlock Text="{Binding EmployeeNumber}"/>  
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
                        </GridViewColumn> 
                      
                        <GridViewColumn  Width="50">  
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
                                    <Button Content="delete" Command="{Binding Path=Delete}" HorizontalAlignment="Left" VerticalAlignment="Top" />                                    
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
     
                        </GridViewColumn> 
                    </GridView> 
                  
                </ListView.View> 
            </ListView> 
     
        </Grid> 
    </Window> 
     

    C#:
    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    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 System.Collections.ObjectModel;  
     
    namespace DummyProject  
    {  
        /// <summary>  
        /// Interaction logic for Window1.xaml  
        /// </summary>  
        public partial class Window1 : Window  
        {  
            public Window1()  
            {         
                InitializeComponent();  
                this.DataContext = new MainViewModel();  
            }     
        }  
     
        public class MainViewModel  
        {  
            ObservableCollection<EmployeeInfoViewModel> _list = new ObservableCollection<EmployeeInfoViewModel>();  
     
            public MainViewModel()  
            {  
                _list.Add(new EmployeeInfoViewModel(thisnew EmployeeInfo("Jesper""Aaberg""12345")));  
                _list.Add(new EmployeeInfoViewModel(thisnew EmployeeInfo("Dominik""Paiha""98765")));  
                _list.Add(new EmployeeInfoViewModel(thisnew EmployeeInfo("Yale""Li""23875")));  
                _list.Add(new EmployeeInfoViewModel(thisnew EmployeeInfo("Muru""Subramani""49392")));  
            }  
     
            public ObservableCollection<EmployeeInfoViewModel> EmployeeInfos  
            {  
                get { return _list; }  
            }  
        }  
     
        public class EmployeeInfoViewModel  
        {  
            private EmployeeInfo _employeeInfo;  
            MainViewModel _mainViewModel;  
     
            public EmployeeInfoViewModel(MainViewModel mainViewModel, EmployeeInfo employeeInfo)  
            {  
                _mainViewModel = mainViewModel;  
                _employeeInfo = employeeInfo;  
            }  
     
            public string FirstName  
            {  
                get { return _employeeInfo.FirstName; }  
            }  
     
            public string LastName  
            {  
                get { return _employeeInfo.LastName; }  
            }  
     
            public string EmployeeNumber  
            {  
                get { return _employeeInfo.EmployeeNumber; }  
            }  
     
            public ICommand Delete  
            {  
                get { return new DelegateCommand(this.OnDelete); }  
            }  
     
            private void OnDelete()  
            {  
                _mainViewModel.EmployeeInfos.Remove(this);  
            }  
        }  
     
        public class EmployeeInfo  
        {  
            public string FirstName { getset; }  
            public string LastName { getset; }  
            public string EmployeeNumber { getset; }  
     
            public EmployeeInfo(string firstname, string lastname, string empnumber)  
            {  
                this.FirstName = firstname;  
                this.LastName = lastname;  
                this.EmployeeNumber = empnumber;  
            }  
        }  
     
        public class DelegateCommand : ICommand  
        {  
            public delegate void SimpleEventHandler();  
            private SimpleEventHandler handler;  
            private bool isEnabled = true;  
     
            public event EventHandler CanExecuteChanged;  
     
            public DelegateCommand(SimpleEventHandler handler)  
            {  
                this.handler = handler;  
            }  
     
            private void OnCanExecuteChanged()  
            {  
                if (this.CanExecuteChanged != null)  
                {  
                    this.CanExecuteChanged(this, EventArgs.Empty);  
                }  
            }  
     
            bool ICommand.CanExecute(object arg)  
            {  
                return this.IsEnabled;  
            }  
     
            void ICommand.Execute(object arg)  
            {  
                this.handler();  
            }  
     
            public bool IsEnabled  
            {  
                get { return this.isEnabled; }  
     
                set 
                {  
                    this.isEnabled = value;  
                    this.OnCanExecuteChanged();  
                }  
            }  
        }  
    }  
     
    • Marked as answer by Tao Liang Wednesday, February 25, 2009 3:53 AM
    Monday, February 23, 2009 11:34 AM

All replies

  • You can save the index  of the row need to be deleted in the Tag of button.
    When the button is clicked, retrieve the index by the tag of button.
    And then remove it from the data source.
    Re bind the data source to listview at last.

    I build a demo project to show this approach:
    XAML
    <Window x:Class="_temple.Window1" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            xmlns:local="clr-namespace:_temple" 
            Loaded="Window_Loaded" 
        Title="Window1" Height="300" Width="600"
          
     
        <Grid> 
            <ListView x:Name="MyListView"  Margin="0,65,12,0"
                <ListView.View> 
                    <GridView  AllowsColumnReorder="true" 
                        ColumnHeaderToolTip="Employee Information"
                  
                        <GridViewColumn   
                             
                            
                                Header="First Name" Width="100"
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
                                    
                                        <StackPanel Width="100" > 
                                            <TextBlock Text="{Binding FirstName}"/> 
                                        </StackPanel> 
                                   
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
     
                        </GridViewColumn> 
                        <GridViewColumn  
                                Header="Last Name" Width="100"
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
                                     
                                        <StackPanel Width="100" > 
                                            <TextBlock Text="{Binding LastName}"/> 
                                        </StackPanel> 
                              
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
                        </GridViewColumn> 
                        <GridViewColumn  
                                Header="Employee No." Width="100"
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
                                     
                                        <StackPanel Width="100"  > 
                                            <TextBlock Text="{Binding EmployeeNumber}"/> 
                                        </StackPanel> 
                                  
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
                        </GridViewColumn> 
                        <GridViewColumn  x:Name="gridClm_SelectRow" Width="50"
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
     
                                    <Button x:Name="btnDelete"  
                                             Tag="{Binding Index}" 
                                                HorizontalAlignment="Left"  
                                                VerticalAlignment="Top"  
                                                 Click="btnDelete_Click" > 
                                        delete 
                                    </Button> 
     
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
     
                        </GridViewColumn> 
                    </GridView> 
                </ListView.View> 
            </ListView> 
      
        </Grid> 
    </Window> 
     

    C#:
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    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.Navigation; 
    using System.Windows.Shapes; 
    using System.ComponentModel; 
    using System.Collections.ObjectModel; 
     
    namespace _temple 
        /// <summary> 
        /// Interaction logic for Window1.xaml 
        /// </summary> 
        public partial class Window1 : Window 
        { 
            ObservableCollection<EmployeeInfo> list = new ObservableCollection<EmployeeInfo>(); 
            public Window1() 
            { 
                list.Add(new EmployeeInfo("Jesper", "Aaberg", "12345")); 
                list.Add(new EmployeeInfo("Dominik", "Paiha", "98765")); 
                list.Add(new EmployeeInfo("Yale", "Li", "23875")); 
                list.Add(new EmployeeInfo("Muru", "Subramani", "49392")); 
                SetOrder(list); 
     
                InitializeComponent(); 
         
            } 
     
            public void SetOrder(  ObservableCollection<EmployeeInfo> data ) 
            { 
                for (int i = 0; i < data.Count; i++) 
                { 
                    EmployeeInfo ei = (EmployeeInfo)data[i]; 
                    ei.Index = i.ToString(); 
                } 
            } 
     
            private void btnDelete_Click(object sender, RoutedEventArgs e) 
            { 
                Button btn = (Button)sender; 
                int index = int.Parse(btn.Tag.ToString()); 
                list.RemoveAt(index); 
                SetOrder(list); 
                MyListView.ItemsSource = null
                MyListView.ItemsSource = list
            } 
     
            private void Window_Loaded(object sender, RoutedEventArgs e) 
            { 
                MyListView.ItemsSource = list
            } 
        } 
     
        public class EmployeeInfo 
        { 
            private string _firstName; 
            private string _lastName; 
            private string _employeeNumber; 
            public string FirstName 
            { 
                get { return _firstName; } 
                set { _firstName = value; } 
            } 
     
            public string LastName 
            { 
                get { return _lastName; } 
                set { _lastName = value; } 
            } 
     
            public string EmployeeNumber 
            { 
                get { return _employeeNumber; } 
                set { _employeeNumber = value; } 
            } 
     
            public string Index { set; get;  } 
       
     
            public EmployeeInfo(  string firstname, string lastname, string empnumber) 
            {  
                _firstName = firstname
                _lastName = lastname
                _employeeNumber = empnumber
            } 
     
             
        } 
       
     

    Hope it helps.

    ----------------------------------------------------------

    Please mark this thread as answer if you think it is helpful.

    Thank you!

    • Proposed as answer by Tao Liang Monday, February 23, 2009 10:01 AM
    • Marked as answer by Tao Liang Wednesday, February 25, 2009 3:53 AM
    Monday, February 23, 2009 10:01 AM
  • Hi liangtom,

    your answer works fine, but I think we should keep unittesting in mind? I prefere the MVVM approach, so I have taken your sample to show how I would do it.

    As you can see the Window1 codebehind is gone. No click event handler and no index is needed.

    What do you think about my solution?

    XAML:
    <Window x:Class="DummyProject.Window1" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
        xmlns:local="clr-namespace:DummyProject"          
        Title="Window1" Height="300" Width="600">  
          
        <Grid> 
            <ListView Margin="0,65,12,0" ItemsSource="{Binding EmployeeInfos}">  
                <ListView.View> 
                    <GridView  AllowsColumnReorder="true"    
                        ColumnHeaderToolTip="Employee Information">  
     
                        <GridViewColumn  Header="First Name" Width="100">  
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate>                            
                                        <TextBlock Text="{Binding FirstName}"/>                               
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
                        </GridViewColumn> 
                          
                        <GridViewColumn Header="Last Name" Width="100">  
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
                                        <TextBlock Text="{Binding LastName}"/>  
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
                        </GridViewColumn> 
                          
                        <GridViewColumn  Header="Employee No." Width="100">  
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
                                        <TextBlock Text="{Binding EmployeeNumber}"/>  
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
                        </GridViewColumn> 
                      
                        <GridViewColumn  Width="50">  
                            <GridViewColumn.CellTemplate> 
                                <DataTemplate> 
                                    <Button Content="delete" Command="{Binding Path=Delete}" HorizontalAlignment="Left" VerticalAlignment="Top" />                                    
                                </DataTemplate> 
                            </GridViewColumn.CellTemplate> 
     
                        </GridViewColumn> 
                    </GridView> 
                  
                </ListView.View> 
            </ListView> 
     
        </Grid> 
    </Window> 
     

    C#:
    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    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 System.Collections.ObjectModel;  
     
    namespace DummyProject  
    {  
        /// <summary>  
        /// Interaction logic for Window1.xaml  
        /// </summary>  
        public partial class Window1 : Window  
        {  
            public Window1()  
            {         
                InitializeComponent();  
                this.DataContext = new MainViewModel();  
            }     
        }  
     
        public class MainViewModel  
        {  
            ObservableCollection<EmployeeInfoViewModel> _list = new ObservableCollection<EmployeeInfoViewModel>();  
     
            public MainViewModel()  
            {  
                _list.Add(new EmployeeInfoViewModel(thisnew EmployeeInfo("Jesper""Aaberg""12345")));  
                _list.Add(new EmployeeInfoViewModel(thisnew EmployeeInfo("Dominik""Paiha""98765")));  
                _list.Add(new EmployeeInfoViewModel(thisnew EmployeeInfo("Yale""Li""23875")));  
                _list.Add(new EmployeeInfoViewModel(thisnew EmployeeInfo("Muru""Subramani""49392")));  
            }  
     
            public ObservableCollection<EmployeeInfoViewModel> EmployeeInfos  
            {  
                get { return _list; }  
            }  
        }  
     
        public class EmployeeInfoViewModel  
        {  
            private EmployeeInfo _employeeInfo;  
            MainViewModel _mainViewModel;  
     
            public EmployeeInfoViewModel(MainViewModel mainViewModel, EmployeeInfo employeeInfo)  
            {  
                _mainViewModel = mainViewModel;  
                _employeeInfo = employeeInfo;  
            }  
     
            public string FirstName  
            {  
                get { return _employeeInfo.FirstName; }  
            }  
     
            public string LastName  
            {  
                get { return _employeeInfo.LastName; }  
            }  
     
            public string EmployeeNumber  
            {  
                get { return _employeeInfo.EmployeeNumber; }  
            }  
     
            public ICommand Delete  
            {  
                get { return new DelegateCommand(this.OnDelete); }  
            }  
     
            private void OnDelete()  
            {  
                _mainViewModel.EmployeeInfos.Remove(this);  
            }  
        }  
     
        public class EmployeeInfo  
        {  
            public string FirstName { getset; }  
            public string LastName { getset; }  
            public string EmployeeNumber { getset; }  
     
            public EmployeeInfo(string firstname, string lastname, string empnumber)  
            {  
                this.FirstName = firstname;  
                this.LastName = lastname;  
                this.EmployeeNumber = empnumber;  
            }  
        }  
     
        public class DelegateCommand : ICommand  
        {  
            public delegate void SimpleEventHandler();  
            private SimpleEventHandler handler;  
            private bool isEnabled = true;  
     
            public event EventHandler CanExecuteChanged;  
     
            public DelegateCommand(SimpleEventHandler handler)  
            {  
                this.handler = handler;  
            }  
     
            private void OnCanExecuteChanged()  
            {  
                if (this.CanExecuteChanged != null)  
                {  
                    this.CanExecuteChanged(this, EventArgs.Empty);  
                }  
            }  
     
            bool ICommand.CanExecute(object arg)  
            {  
                return this.IsEnabled;  
            }  
     
            void ICommand.Execute(object arg)  
            {  
                this.handler();  
            }  
     
            public bool IsEnabled  
            {  
                get { return this.isEnabled; }  
     
                set 
                {  
                    this.isEnabled = value;  
                    this.OnCanExecuteChanged();  
                }  
            }  
        }  
    }  
     
    • Marked as answer by Tao Liang Wednesday, February 25, 2009 3:53 AM
    Monday, February 23, 2009 11:34 AM
  • To Guenter:
    Your code is great and beautiful!
    Wednesday, February 25, 2009 3:52 AM