Pass sequence of steps (methods) to window (wpf)

Asked

Viewed 88 times

0

Greetings...I currently have a screen similar to the one presented below: inserir a descrição da imagem aqui

This screen uses Backgroundworker to perform a sequence of steps and inform the user through the messages in the textblock a step by step of the tasks currently being performed.

After the end of the last step, the log and close buttons are displayed and Progressbar (below the buttons) is stopped, thus informing the end of the processing.

I would like to reuse this screen for other operations, whose number of steps, each operation will have its own, so I don’t know how to exemplify, but I would like to pass to the screen an operation with several steps to be executed, at another time would pass another operation with several other steps...I want to reuse the features of save log and inform the user step by step.

I thought of something according to the classes below, but I don’t know where to start:

public class Operacao1
{
    public void Inicia()
    {
        // Gostaria de atualizar a tela aqui!
        Passo1();
        // Aguarda a finalização do passo 1
        Passo2();
        // Aguarda a finalização do passo 2
        Passo3();
        // Gostaria de atualizar a tela aqui!
    }

    private void Passo1()
    {
        // Gostaria de atualizar a tela aqui!
        // implemento a funcionalidade...
        // Atualizo novamente a tela aqui!
    }

    private void Passo2()
    {
        // Gostaria de atualizar a tela aqui!
        // implemento a funcionalidade...
        // Atualizo novamente a tela aqui!
    }

    private void Passo3()
    {
        // Gostaria de atualizar a tela aqui!
        // implemento a funcionalidade...
        // Atualizo novamente a tela aqui!
    }
}

public class Operacao2
{
    public void Inicia()
    {
        // Gostaria de atualizar a tela aqui!
        Passo1();
        // Aguarda a finalização do passo 1
        Passo2();
        // Gostaria de atualizar a tela aqui!
    }

    private void Passo1()
    {
        // Gostaria de atualizar a tela aqui!
        // implemento a funcionalidade...
        // Atualizo novamente a tela aqui!
    }

    private void Passo2()
    {
        // Gostaria de atualizar a tela aqui!
        // implemento a funcionalidade...
        // Atualizo novamente a tela aqui!
    }
}

I wanted a north to know if the Backgroundworker would work, or if I had to use task, etc...I appreciate any help!

1 answer

1

Next Paul, what I understand is that you want a reusable screen, I will try to give you a light to continue.

First, let me take your doubt below:

I wanted a north to know if the Backgroundworker would work, or if I had to use task, etc...I appreciate any help!

Like Stephen Cleary explains in his blog: http://blog.stephencleary.com/2013/09/taskrun-vs-backgroundworker-conclusion.html

Backgroundworker is a type that should not be used in new code. Everything it can do, Task.Run can do Better; and Task.Run can do a Lot of Things that Backgroundworker can’t!

Reading the article makes it clear that the Backgroundworker can even be replaced by the Task. Recalling that the article is from 2013, it has been 4 years that this was mentioned.

On your problem, I have made the following resolution:

I created a UserControl containing:

Usercontrol1.xaml

<Grid>
    <Label Content="OPERANDO" HorizontalAlignment="Center" FontSize="20"/>
    <ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto" Margin="40">
        <StackPanel x:Name="spResultado" Background="White">

        </StackPanel>
    </ScrollViewer>
</Grid>

The code of the Usercontrol

Usercontrol1.Cs

 public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
    }

    public async Task<bool> ExecutaAcao(Func<bool> Acao)
    {
        Task<bool> task = new Task<bool>(Acao);
        task.Start();
        await task;
        return task.Result;
    }

    public void InformaAcao(string value)
    {
        TextBlock txt = new TextBlock { Text = value };
        spResultado.Children.Add(txt);
    }

    public void ExibeResultado(string value)
    {
        TextBlock txt = new TextBlock { Text = value, Foreground = Brushes.Green };
        spResultado.Children.Add(txt);
    }

}

Our Usercontrol is ready to receive the information (remembering that this is just an example).

The idea is to put this Usercontrol where you need it and pass the information on to him to process.

In Your Interface Window add it:

Window.xaml

<local:UserControl1 x:Name="UserControl1"/>

In the code of your Window he’ll be like this:

Window.Cs

 //CRIA UM FUNC QUE RETORNARÁ TRUE OU FALSO PARA 
        Func<bool> baixaArquivos = new Func<bool>(() =>
        {
            // SEU PROCEDIMENTO AQUI
            // REMOVER ESSE THREAD.SLEEP, COLOQUEI ELE APENAS PARA SEGURAR O PROCESSO POR 5s
            System.Threading.Thread.Sleep(5000);
            // CASO SEU PROCEDIMENTO TEVE SUCESSO, RETORNE TRUE
            return true;
        });

        Func<bool> removeArquivos = new Func<bool>(() =>
        {
            System.Threading.Thread.Sleep(5000);
            return true;
        });
        Func<bool> instalaSistema = new Func<bool>(() =>
        {
            System.Threading.Thread.Sleep(5000);
            return true;
        });

        //INFORMA O USUARIO SOBRE QUAL PROCESSO ESTÁ SENDO EXECUTADO
        UserControl1.InformaAcao("Inicia processo de download do arquivo");
        //EXECUTA DE MANEIRA ASSINCRÓNICA A FUNC CRIADA ACIMA E RETORNA O STATUS
        if (await UserControl1.ExecutaAcao(baixaArquivos) == true) { UserControl1.ExibeResultado("Sucesso no download"); } else { MessageBox.Show("Erro na operação"); return; }


        UserControl1.InformaAcao("Remove antigos arquivos");
        if (await UserControl1.ExecutaAcao(removeArquivos) == true) { UserControl1.ExibeResultado("Sucesso na remoção dos arquivos"); } else { MessageBox.Show("Erro na operação"); return; }
        UserControl1.InformaAcao("Instalando novo sistema");
        if (await UserControl1.ExecutaAcao(instalaSistema) == true) { UserControl1.ExibeResultado("Sucesso ao instalar sistema"); } else { MessageBox.Show("Erro na operação"); return; }

This was just one example, there are other ways to do it. You can do it with or without the UserControl, is at your discretion. You can also pass a Action or something else in place of FUNC.

Any questions, just ask. Good Luck

Browser other questions tagged

You are not signed in. Login or sign up in order to post.