Andrei
Andrei

Reputation: 217

invalidcastexception when trying to convert from ListBox object to MyListBox : ListBox object in WPF

I use a ListBox in my code to store some csv files selected by the user:

<ListBox x:Name="emailsFilesListBox" HorizontalAlignment="Left" Height="67" Margin="10,254,0,0" Grid.Row="1" VerticalAlignment="Top" Width="147"/>

In MainWindow.xaml.cs I use a private class to extend System.Windows.Controls.ListBox:

private class MyListBox : System.Windows.Controls.ListBox
        {
            public string[] FullFilesPathsList { get; set; }
            public MyListBox() : base()
            {
            }
        }

Inside an event handler in MainWindow.xaml.cs I have the following code:

  private void emailsAdd_Click(object sender, RoutedEventArgs e)
    {
        Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
        dlg.Multiselect = true;
        dlg.Filter = "CSV Files|*.csv";
        Nullable<bool> result = dlg.ShowDialog();

        if (result == true)
        {
            MyListBox myListBoxWithEmailsFiles = new MyListBox();
            myListBoxWithEmailsFiles = (MyListBox)emailsFilesListBox;
            myListBoxWithEmailsFiles.FullFilesPathsList = dlg.FileNames;
            ....................................

        }
    }

Trying to perform the conversion "myListBoxWithEmailsFiles = (MyListBox)emailsFilesListBox;" leads to an InvalidCastException. Could you tell me why is this possible?

Upvotes: 2

Views: 345

Answers (1)

Grant Winney
Grant Winney

Reputation: 66439

Use MyListBox instead of ListBox by changing the scope of your class from private to public, and then changing your XAML accordingly:

<nameOfYourWpfProject:MyListBox x:Name="emailsFilesListBox" 
    HorizontalAlignment="Left" Height="67" Margin="10,254,0,0" Grid.Row="1" 
    VerticalAlignment="Top" Width="147"/>

You'll have to add something like this to your main Window tag:

xmlns:nameOfYourWpfProject="clr-namespace:NameOfYourWpfProject"

In general, you can't cast a base type to a derived type like that. Another option would be to pass the ListBox in the ctor to your class, and then create properties to expose the ListBox properties you want to access.

private class MyListBox : System.Windows.Controls.ListBox
{
    public string[] FullFilesPathsList { get; set; }

    public MyListBox(ListBox listBox)
    {
        this.listBox = listBox;
    }

    private ListBox listBox;

    public string Name { get { return listBox.Name; } }
}

That shouldn't be necessary in this case, if you just use MyListBox in place of ListBox.

Upvotes: 2

Related Questions