locked
ListBox SelectedIndex changed with KeyDown RRS feed

  • Question

  • Hi,

    Not sure if this is the right place to post my question. I have a ListBox in my WPF application with a list of files that the user selects using the arrow keys. So the issue is when user finds an item that need to be deleted, then he/she will hit the Delete key to delete that item and the selectedIndex will be moved to the previous item. But when the user hit the down arrow key again to select the next item, the selectedIndex automatically change to 0. For example:

    SelectedIndex = 4;
    Hit delete Key: new SelectedIndex = 3 and item index 4 deleted.
    Hit down arrow Key: SelectedIndex = 4 but first item in ListBox is selected instead.

    Using C# and .NET 4.0


    Alex Su

    Friday, September 5, 2014 2:03 AM

Answers

  • Hi Alex,

    Refer below code.

    <Window x:Class="ListBox_Delete.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <ListBox x:Name="lst" PreviewKeyDown="lst_PreviewKeyDown"
                     DisplayMemberPath="Name"></ListBox>
        </Grid>
    </Window>
    

    public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                DirectoryInfo dinfo = new DirectoryInfo(@"C:\Test");
                FileInfo[] Files = dinfo.GetFiles("*.txt");
                foreach (FileInfo file in Files)
                {
                    lst.Items.Add(file);
                }
            }
    
            private void lst_PreviewKeyDown(object sender, KeyEventArgs e)
            {
                if (e.Key == Key.Delete)
                {
                    this.DeleteSelectedFile();
                    e.Handled = true;
                }
            }
            private void DeleteSelectedFile()
            {
                if (lst.SelectedItem != null)
                {
                    int int_selectedIndex = lst.SelectedIndex;
                    FileInfo fi_toDelete = (FileInfo)lst.SelectedItem;
                    ListBoxItem lbi=null;
    
                    if (lst.Items.Count > 1)
                    {
                        if (int_selectedIndex == 0)
                        {
                             lbi = (ListBoxItem)lst.ItemContainerGenerator.ContainerFromIndex(0);
                        }
                        else
                        {
                             lbi = (ListBoxItem)lst.ItemContainerGenerator.ContainerFromIndex(int_selectedIndex - 1);
                        }
                    }
    
    
                    lst.Items.RemoveAt(int_selectedIndex);
                    
                    lbi.Focus();
                    
                }
            }
        }

    • Marked as answer by Alex Su10 Friday, September 5, 2014 5:22 AM
    Friday, September 5, 2014 4:38 AM

All replies

  • If you can post some of your code, where the selectedindex works or maybe the deleting function?


    Happy Coding!

    Friday, September 5, 2014 3:02 AM
  • The PreviewKeyDown event for the ListBox:

    private void lbx_files_KeyDown( object sender, KeyEventArgs e ) {
    
    	if( e.Key == Key.Delete ) {
    		this.DeleteSelectedFile();
    		e.Handled = true;
    	}
    
    }

    The DeleteSelectedFile() sub:

    private void DeleteSelectedFile() {
    	if( lbx_files.SelectedItem != null ) {
    		int int_selectedIndex = lbx_files.SelectedIndex;
    		FileInfo fi_toDelete = ( FileInfo )lbx_files.SelectedItem;
    
    		if( lbx_files.Items.Count > 1 ) {
    			if( int_selectedIndex == 0 ) {
    				lbx_files.SelectedIndex = 0;
    			} else {
    				lbx_files.SelectedIndex = int_selectedIndex - 1;
    			}
    		}
    
    		Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile( fi_toDelete.FullName, Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs, Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin );
    		lbx_files.Items.Remove( fi_toDelete );
    	}
    }


    Alex Su

    Friday, September 5, 2014 3:08 AM
  • Hi Alex,

    Refer below code.

    <Window x:Class="ListBox_Delete.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <ListBox x:Name="lst" PreviewKeyDown="lst_PreviewKeyDown"
                     DisplayMemberPath="Name"></ListBox>
        </Grid>
    </Window>
    

    public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                DirectoryInfo dinfo = new DirectoryInfo(@"C:\Test");
                FileInfo[] Files = dinfo.GetFiles("*.txt");
                foreach (FileInfo file in Files)
                {
                    lst.Items.Add(file);
                }
            }
    
            private void lst_PreviewKeyDown(object sender, KeyEventArgs e)
            {
                if (e.Key == Key.Delete)
                {
                    this.DeleteSelectedFile();
                    e.Handled = true;
                }
            }
            private void DeleteSelectedFile()
            {
                if (lst.SelectedItem != null)
                {
                    int int_selectedIndex = lst.SelectedIndex;
                    FileInfo fi_toDelete = (FileInfo)lst.SelectedItem;
                    ListBoxItem lbi=null;
    
                    if (lst.Items.Count > 1)
                    {
                        if (int_selectedIndex == 0)
                        {
                             lbi = (ListBoxItem)lst.ItemContainerGenerator.ContainerFromIndex(0);
                        }
                        else
                        {
                             lbi = (ListBoxItem)lst.ItemContainerGenerator.ContainerFromIndex(int_selectedIndex - 1);
                        }
                    }
    
    
                    lst.Items.RemoveAt(int_selectedIndex);
                    
                    lbi.Focus();
                    
                }
            }
        }

    • Marked as answer by Alex Su10 Friday, September 5, 2014 5:22 AM
    Friday, September 5, 2014 4:38 AM
  • Thank you so much! It works as I wanted it to!

    I guess I need to stop thinking the WinForms way, nothing is as I expected it to be.

    I have modified to code to the resulting code below:

    private void DeleteSelectedFile() {
    
    	if( lbx_files.SelectedItem != null ) {
    
    		int int_selectedIndex = lbx_files.SelectedIndex;
    		FileInfo fi_toDelete = ( FileInfo )lbx_files.SelectedItem;
    
    		( ( ListBoxItem )lbx_files.ItemContainerGenerator.ContainerFromIndex( ( lbx_files.Items.Count > 1 ? ( int_selectedIndex == 0 ? 1 : int_selectedIndex - 1 ) : 0 ) ) ).Focus();
    				
    		Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile( fi_toDelete.FullName, Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs, Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin );
    		lbx_files.Items.RemoveAt( int_selectedIndex );
    
    	}
    
    }


    Alex Su

    Friday, September 5, 2014 5:24 AM