C# WPF Hello World 3


This entry is part 3 of 4 in the series WPF Hello World

Following along with the previous post we will create a new WPF program with the Browse button by adding a new User Control and copying the XAML code over from the previous post. After it is copied over, we need to change the x:class to be sure we are using the name of our application: WpfApp3 and not WpfApp2. This is required.

Now we need to write the logic code in the XamlFileBrowser.xaml.cs file. We can copy the code over from the previous post. We then need to change the namespace from WpfApp2 to ApfApp3. This is required. If we don’t change it over we get a complaint from Intelisense saying the FBCTextBox does not exist in the current context.

The next step is to include the User Control in the window of the main application. To do this we open the mainWindow.xaml file by double-clicking it in Solution Explorer. Between the two Grid tags we add the following code.

        <local:XamlFileBrowser Loaded="XamlFileBrowser_Loaded"  />

In the MainWindow.xaml.cs file we need to add some code, shown below.

        private void XamlFileBrowser_Loaded(object sender, RoutedEventArgs e)
        {
        }

Process File

The project should be working now. If you run it you should see the Browse button and the text box.

We need to do something with the file the user selected. If it is a text file we can read the number of words in the file and report that back to the user. That’s not particularly useful as any descent text editor should be able to do that, but it illustrates how we can load a file and use string functions to parse it.

To meet these requirements we could create two classes. One class will be our file processor. The other class could contain all of or sting functions. Before we open the file, we should check that the file exists and that is has an extension of TXT. We could create a class called FileProcessor that has a method called CharsInFile. We could create a class called StringProcessor that has static string methods that accept string parameters and returns strings. We could have a WordCount method that returns an integer representing the number of words in the file. Let’s just start without our StringProcessor and write the CharsInFile() method.

We can write the classes first and then focus on the event that calls the FileProcessor and its method ImportFile. We will need to pass the file name to the ImportFile method.

Right-click the project, Add, Class and name it ProcessFile. We get the following code. This is just to get started. The next listing shows the code we added.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp3
{
    class ProcessFile
    {
    }
}

File Processing

Let’s write our code and end up with the following. Here is where we implement what we do with the filename and path we received from the user. Why did we ask the use for a file in the first place? In our example, all we do is show a message box that tells the user how many characters were in the file they selected. In a real-world application we might be processing that file and manipulating data and creating a new file, for example. We could use StreamWriter for the purpose of creating a new file.

using System.Windows;
using System.IO;

namespace WpfApp3
{
    class ProcessFile
    {
        public static int CharsInFile(string strSourcePath)
        {
            int CharCount = 0;
            // If the file extension is not txt then show message box, otherwise continue
            string strExtension = Path.GetExtension(strSourcePath);
            if (strExtension.ToUpper() != ".TXT")
            {
                MessageBox.Show("The file name must be a text file with a .txt extension.\nPlease choose again.");
            }
            else
            {
                if (File.Exists(strSourcePath))
                {
                    // Now let's open the file
                    string FileText = new System.IO.StreamReader(strSourcePath).ReadToEnd().Replace("\r\n", string.Empty);
                    CharCount = FileText.Length;            //total char 
                    MessageBox.Show(CharCount.ToString() + " characters in file.");
                }
                else
                {
                    MessageBox.Show("File not found. Please try again.");
                }
            }
            return CharCount;
        }
    }
}

Event

On a certain event, TextChanged of the text box, we can call our method this way: ProcessFile.CharsInFile(this.FileName). The pattern of this is class.method(property). Below is the listing of XamlFileBrowser.xaml.cs to call our method that will show a message box. Alternatively we could put this code in the Click even of the button. I have commented out that code.

using System;
using System.Windows;
using System.Windows.Controls;

namespace WpfApp3
{
    /// <summary>
    /// Interaction logic for XamlFileBrowser.xaml
    /// </summary>
    public partial class XamlFileBrowser : UserControl
    {
        public XamlFileBrowser()
        {
            InitializeComponent();
        }
        public string FileName
        {
            get { return FBCTextBox.Text; }
            set { FBCTextBox.Text = value; }
        }
        private void FBCButton_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog openFileDlg = new Microsoft.Win32.OpenFileDialog();
            if (openFileDlg.ShowDialog() == true)
                this.FileName = openFileDlg.FileName;
                // ProcessFile.CharsInFile(this.FileName);
        }
        public event EventHandler<EventArgs> FileNameChanged;

        private void FBCTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            e.Handled = true;
            if (FileNameChanged != null)
                FileNameChanged(this, EventArgs.Empty);
            ProcessFile.CharsInFile(this.FileName);
        }
    }
}

Accesing mainwindiow controls from other class in WPF

If you have a class that is doing some processing and you need to display a message to a control in the main window you can use the following code (or similar). So instead of displaying a message box, we can simply display a message on the window. In this case, the control is called txtBlock1.

MainWindow win = (MainWindow)Application.Current.MainWindow;
win.txtBlock1.Text = "";
Series Navigation<< C# WPF Hello World 2C# WPF Hello World 4 >>