Besiktas
Besiktas

Reputation: 331

WPF GUI freezing

Stuck with a problem with WPF. I should mention that I'm very very new to WPF. I'm building small apps for myself to understand the topics.

At the moment I'm stuck updating a listbox calling a class that is in my "_classes" folder which gets information from a remote computer. The reason I put it in a different folder was to avoid all the mess behind the XAML. I can get the GUI freezing issue fixed if I want to put my code behind the XAML which is not ideal from what I've been reading.

The examples given or searched on here or other sites are kind of confusing with no explanations. It would be awesome if someone can actually put comments where I'm stuck and point out what I was doing wrong after they correct it. After all I'm trying to learn this. Going forward, whats the best way to implement these kind of long processing tasks? Create a folder? Call classes? Different solutions? Different projects? etc. I've been reading a lot about this and everyone seems to have their own opinion on this.

Also, I searched this and gotten no where. I feel like I'm going to be the first one to ask this but is MVVM necessary for responsive UI? Can I just implement async/await and be done with it like I'm trying to do in the example I have below?

This is the code I have at the moment. Although I get the results I want, the GUI is unresponsive. I added the thread.sleep there to simulate a long process.

Although I tried different things, this is the latest code I have at the moment.

This is what I had in mind that the app would do:

Thank you everyone in advance.

PS. Please ignore the naming conventions for now. I've been working on this for a while and just gave up on that part till I actually fix the issue.

XAML

<StackPanel>

    <Button Name="test" Height="30" Width="70"  Background="red" Content="Submit"
                    Click="test_Click" />

    <ListBox x:Name="listboxResult"  />
</StackPanel>

Code Behind XAML

public partial class MainWindow : Window
{

    public MainWindow()
    {
        InitializeComponent();
    }

    private async void test_Click(object sender, RoutedEventArgs e)
    {
        listboxResult.Items.Clear();
        listboxResult.Items.Add("Getting listbox results...");
        try
        {
            await Task.Factory.StartNew(() =>
            {
                getResults("Passing String Argument", listboxResult);
            });

        }
        catch (Exception)
        {

            throw;
        }

    }

    private void getResults(string v, ListBox listBoxIn)
    {
        this.Dispatcher.Invoke((Action)(() =>
        {
            ReturnListbox _result = new ReturnListbox(v, listBoxIn);
        }));

    }
}

My class in _classes folder

public class ReturnListbox
{
    private ListBox _myListBox;
    private string _ComputerName;
    public ListBox MyListBox
    {
        get { return _myListBox; }
        set { _myListBox = MyListBox; }
    }
    public string CName
    {
        get { return _ComputerNAme; }
        set { _ComputerName = CName; }
    }

    public ReturnListbox(string ComputerName, ListBox IncomingListBox)
    {

        BuildListBox(ComputerName, IncomingListBox);

    }

    private void BuildListBox(string CName, ListBox MyListBox)
    {
        Thread.Sleep(5000);
        _myListBox = MyListBox;
        MyListBox.Items.Clear();


        try
        {
          ManagementScope Manage = new ManagementScope(string.Format("\\\\{0}\\root\\cimv2", CName));
                    Manage.Connect();
                    ObjectGetOptions objectOptions = new ObjectGetOptions();
                    ManagementPath managementPath = new ManagementPath("Win32_OperatingSystem");
                    ManagementClass Class = new ManagementClass(Manage, managementPath, objectOptions);

                    foreach (ManagementObject Object in Class.GetInstances())
                    {
                        // Display the remote computer information
                        MyListBox.Items.Add(string.Format("Computer Name : {0}", Object["csname"]));
                        MyListBox.Items.Add(string.Format("Windows Directory : {0}", Object["WindowsDirectory"]));
                        MyListBox.Items.Add(string.Format("Operating System: {0}", Object["Caption"]));
                        MyListBox.Items.Add(string.Format("Version: {0}", Object["Version"]));
                        MyListBox.Items.Add(string.Format("Manufacturer : {0}", Object["Manufacturer"]));

                    }
      {
      catch (Exception ex)
        {
            MyListBox.Items.Add(string.Format("Something is going on..."));

        }
    }

Upvotes: 0

Views: 3427

Answers (1)

Evgeny Gorbovoy
Evgeny Gorbovoy

Reputation: 773

You can read about async programming in WPF here

It would be awesome if someone can actually put comments where I'm stuck

What you are using is not MVVM as you think. You also need get more knowledge about threading

is MVVM necessary for responsive UI? Can I just implement async/await and be done with it like I'm trying to do in the example I have below?

MVVM is not necessary. You can use async/await. They are not related to each other

Although I get the results I want, the GUI is unresponsive

Your GUI is unresponsive because you are doing your tasks in UI thread. By calling this.Dispatcher.Invoke you are saying that you want code inside to be executed in Dispatcher thread (which is actually responsible for handling UI)

Upvotes: 1

Related Questions