Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
(WPF) DelegatedTaskedCommand
LaTino
myCSharp.de - Experte

Avatar #avatar-4122.png


Dabei seit:
Beiträge: 3061
Herkunft: Thüringen

Themenstarter:

(WPF) DelegatedTaskedCommand

beantworten | zitieren | melden

Beschreibung:
Ein typisiertes Command, das einen beliebigen übergeben Delegaten im Hintergrund ausführt.
(Ich habe eine Pre-4.0-Klasse, die dasselbe mit dem Backgroundworker machte, durch diese ersetzt und finde das Konzept ganz praktisch. Lässt sich sicher noch entschlacken. Und ja, man kann damit sein MVVM kaputtmachen. MVVM Toolkit ist bekannt, aber unerwünscht.)


//Abstrakte Basisklasse für Hintergrund-Commands
public abstract class TaskedCommandBase : ICommand
{
    private bool _isExecuting;
    public bool IsExecuting
    {
        get
        {
            return _isExecuting;
        }
        set
        {
            if (value.Equals(_isExecuting)) return;
            _isExecuting = value;
            OnCanExecuteChanged();
        }
    }

    protected void OnCanExecuteChanged()
    {
        var handler = CanExecuteChanged;
        if (handler != null) 
            handler(this, EventArgs.Empty);
    }

    public bool CanExecute(object parameter)
    {
        return !IsExecuting;
    }

    public async void Execute(object parameter)
    {
        OnBeforeWork(this, parameter);
        await Task.Run(() =>
        {
            IsExecuting = true;
            OnExecute(this, parameter);
            IsExecuting = false;
        });
        OnAfterWork(this, parameter);
    }

    public abstract void OnBeforeWork(object sender, object parameter);
    public abstract void OnExecute(object sender, object parameter);
    public abstract void OnAfterWork(object sender, object parameter);

    public event EventHandler CanExecuteChanged;
}


//Implementierung mit Delegaten (Action<>)
public class DelegatedTaskedCommand<T> : TaskedCommandBase
{
    private readonly Action<object, T> _beforeWorkAction;
    private readonly Action<object, T> _afterWorkAction;
    private readonly Action<object, T> _executeAction;

    public DelegatedTaskedCommand(Action<object, T> executeAction, Action<object, T> afterWorkAction = null, Action<object, T> beforeWorkAction = null)
    {
        _beforeWorkAction = beforeWorkAction;
        _afterWorkAction = afterWorkAction;
        _executeAction = executeAction;
    }

    public override void OnBeforeWork(object sender, object parameter)
    {
        ExecuteAction(sender, parameter, _beforeWorkAction);
    }

    public override void OnExecute(object sender, object parameter)
    {
        ExecuteAction(sender, parameter, _executeAction);
    }

    public override void OnAfterWork(object sender, object parameter)
    {
        ExecuteAction(sender, parameter, _afterWorkAction);
    }

    private void ExecuteAction(object sender, object parameter, Action<object, T> action)
    {
        if (!(parameter is T)) return;
        if (action != null) action(sender, (T)parameter);
    }
}


//Anwendung für einen View mit einem ProgressBar, der an die VM-Eigenschaft "OperationProgress" gebunden ist, mit einem string als Parameter
//ViewModel
public ICommand TestCommand
{
    get
    {
        IProgress<int> progressHandler = new Progress<int>(value => OperationProgress = value);
        return new DelegatedTaskedCommand<string>((sender, param) =>
        {
            var stringBuilder = new StringBuilder(param);
            for (var i = 0; i < 100; i++)
            {
                progressHandler.Report(i+1);
                Thread.Sleep(100);
                stringBuilder.Append(i.ToString());
            }
            _stringMember = stringBuilder.ToString();
        }); 
    }
}

WPF, ICommand, Task
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
private Nachricht | Beiträge des Benutzers