views:

414

answers:

2

hello,

I have a TextBox in StatusBar in wpf which i want to update.

I have a list of files in ListBox. On each file I would be doing some operation by calling say method ProcessFile(). So whenever the file processing is completed I want to show that file's name in the StatusBar text.

I have tried something like this:

private void button_Click(object sender, RoutedEventArgs e)
    {

        statusBar.Visibility = Visibility.Visible;

        DispatcherFrame frame = new DispatcherFrame();
        Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(TimeConsumingMethod), frame);
        Dispatcher.PushFrame(frame);
        statusBar.Visibility = Visibility.Collapsed;
    }

    public object TimeConsumingMethod(Object arg)
    {
        ((DispatcherFrame)arg).Continue = false;

        foreach (string fileName in destinationFilesList.Items)
        {
            txtStatus.Text = fileName.ToString();
            //Assume that each process takes some time to complete
            System.Threading.Thread.Sleep(1000);
        }
        return null;
    }

But i can only see the last file's name in the StatusBar. Whats wrong with the code? Can somebody correct it? Thanks.

A: 

When you are using a ViewModel, i would define a Property "ProcessedFile" in your ViewModel and bind the Textbox of your StatusBar to the Property.

Every time you processed a file i would set the Property "ProcessedFile" to the name of the file.

Here´s some code for the ViewModel.

public class ViewModel : INotifyPropertyChanged {
    private string _processedFile;
    public string ProcessedFile {
        get {
            return _processedFile;
        }
        set {

            if (_processedFile != value) {
                _processedFile = value;

                if (PropertyChanged != null) {
                    PropertyChanged(this, new PropertyChangedEventArgs("ProcessedFile"));
                }
            }
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    public void ProcessFile() {
       // Process the file
       ProcessedFile = //Set the Property to the processed file
    }
}

Heres the XAML to bind the TextBox to the Property. (I assume that the ViewModel is set as DataContext for the TextBox)

<TextBox Text="{Binding ProcessedFile, Mode=OneWay}"/>
Jehof
+1  A: 

There's more ways to do this.

Set content directly from code
You need give name to the TextBox so that you can access it's content:

XAML

<TextBox x:Name="myTextBox" />

C#

...
ProcessFile(someFileName);
myTextBox.Text = someFileName;

Use data binding
You need to create some object and set it as DataContext to the TextBox or some WPF element that contain that text box (status bar, window, ...).

XAML:

<TextBox Text="{Binding Path=ProcessedFileName}" />

C#

public MyClass : INotifyPropertyChanged
{
    public string ProcessedFileName {get; set;} 

    public void ProcessFile(string someFileName)
    {
       // Processing file code here

       // When done processing, set file name to property
       ProcessedFileName = someFileName;
       OnPropertyChanged("ProcessedFileName");
    } 

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
} 

For more information on data binding see Data Binding Overview

zendar
why shall i create a spearate class if it can only be done with few lines using Dispatcher?
Archie
See article "Data Binding Overview" for explanation. Link is above at the end of the answer.
zendar