0

I am just trying to migrate some of my old apps from Win-forms to WPF. In my old win-form app I can send an array to a ListBox with the code below.

In my new WPF app, this will not populate the ListBox. What is weird is it does not error out, it just doesn't work.

...well it did error the very first time I tested the app I got a message that said I didn't have permissions, but now it just displays the message saying "done" without doing anything.

private void btnFolderBrowser_Click(object sender, RoutedEventArgs e)
{
    getFileStructure();
    System.Windows.Forms.MessageBox.Show("done!");
}

private void getFileStructure()
{
    string myDir = "";
    int i;
    string filter = txtFilter.Text;

    FolderBrowserDialog fbd = new FolderBrowserDialog();
    fbd.RootFolder = Environment.SpecialFolder.Desktop;
    fbd.ShowNewFolderButton = false;
    fbd.Description = "Browse to the root directory where the files are stored.";

    if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        myDir = fbd.SelectedPath;

    try
    {
        txtRootDir.Text = fbd.SelectedPath;
        string[] fileName = Directory.GetFiles(myDir, filter, SearchOption.AllDirectories);

        for (i = 0; i < fileName.Length; i++)
            lstFileNames.Items.Add(fileName[i]);
    }

    catch (System.Exception excep)
    {
        System.Windows.Forms.MessageBox.Show(excep.Message);
        return;
    }
}
3
  • Did you try putting a breakpoint to make sure the list is actually being populated? Commented Feb 3, 2013 at 22:55
  • So is there anything in fileName?, ps not well named that is it... Commented Feb 3, 2013 at 22:56
  • what do you mean not well named? Sorry if that is a dumb question, I am not a developer but I would like to know proper standards. Commented Feb 4, 2013 at 0:19

1 Answer 1

2

In WPF you should be populating Properties in the code behind and binding you UI elements to those properties, its not good practice to reference/access UIElements from the code behind.

Here is a mockup example based on what I think you are trying to do.

Xaml:

<Window x:Class="WpfApplication14.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" Name="UI">
    <StackPanel DataContext="{Binding ElementName=UI}">
        <TextBox Text="{Binding TextRootDir}" IsReadOnly="True" />
        <ListBox ItemsSource="{Binding MyFiles}" SelectedItem="{Binding SelectedFile}" Height="244" />
        <TextBox Text="{Binding TextFilter, UpdateSourceTrigger=PropertyChanged}" />
        <Button Content="Browse" Click="btnFolderBrowser_Click" >
            <Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Setter Property="IsEnabled" Value="True" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding TextFilter}" Value="">
                            <Setter Property="IsEnabled" Value="False" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </StackPanel>

</Window>

Code:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private string _textRootDir;
    private string _textFilter = string.Empty;
    private string _selectedFile;
    private ObservableCollection<string> _myFiles = new ObservableCollection<string>();

    public MainWindow()
    {
        InitializeComponent();
    }

    public ObservableCollection<string> MyFiles
    {
        get { return _myFiles; }
        set { _myFiles = value; }
    }

    public string SelectedFile
    {
        get { return _selectedFile; }
        set { _selectedFile = value; NotifyPropertyChanged("SelectedFile"); }
    }

    public string TextFilter
    {
        get { return _textFilter; }
        set { _textFilter = value; NotifyPropertyChanged("TextFilter"); }
    }

    public string TextRootDir
    {
        get { return _textRootDir; }
        set { _textRootDir = value; NotifyPropertyChanged("TextRootDir"); }
    }

    private void btnFolderBrowser_Click(object sender, RoutedEventArgs e)
    {
        GetFileStructure();
        MessageBox.Show("done!");
    }

    private void GetFileStructure()
    {
        string myDir = "";
        System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog();
        fbd.RootFolder = Environment.SpecialFolder.Desktop;
        fbd.ShowNewFolderButton = false;
        fbd.Description = "Browse to the root directory where the files are stored.";

        if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            myDir = fbd.SelectedPath;
            try
            {
                TextRootDir = fbd.SelectedPath;
                MyFiles.Clear();
                foreach (var file in Directory.GetFiles(myDir, TextFilter, SearchOption.AllDirectories))
                {
                    MyFiles.Add(file);
                }
            }
            catch (Exception excep)
            {
                MessageBox.Show(excep.Message);
                return;
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Result:

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. The embarrassing thing I have to admit is it took me longer to copy paste and get this to work than it did for you to do it from scratch. Now I have to go learn about ObservableCollections.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.