Hi, this is my Homepage, welcome.


This homepage is created with ASP.NET MVC5, bootstrap, jquery, javaScript and HTML5

You found bugs , please contact me.

Find Out More

more details


Qualification Documents

Download any Documents

Astronomy

Articles and more astronomy knowledge.(is coming soon)

technology

technology articles and technology knowledge.(is coming soon)

My PC

My PC Hardware and software (is coming soon)

My Blog

Some thoughts and opinions from me

Code snipes

Any other Interesting links

Interesting links

Any other Interesting links

Code Snipes


Etwas WPF

Manuela Erdmann on

Das RelayCommand

Hi, hier nun ein paar Code Snipes für mich und für euch. So das ist der Anfang, ein RelayCommand. Dient dazu das CanExecute von dem CommandManager auszuführen zulassen. Wenn der CommandManger bemerkt das sich die Oberfläche verändert, führt er alle registrierten CanExecute Methoden der registrierten Commands aus. Wenn wir unsere eigenen Commands im ViewModel benutzen, können wir diese auch im CommandManager registrieren. Damit bleiben die Controls die an den Commands gebunden sind immer synchron mit dem Ergebnis der CanExecute Methode.


    public class RelayCommand : ICommand
    {

        private Action<object> _execute;
        private Func<object, bool> _canExecute;

        public RelayCommand(Action<object> execute, Func<object, bool> canExecute) {
            _canExecute = canExecute;
            _execute = execute;
        }

        public event EventHandler CanExecuteChanged {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public bool CanExecute(object parameter) {
            return _canExecute(parameter);
        }

        public void Execute(object parameter) {
            _execute(parameter);
        }
    }

Etwas WPF

Manuela Erdmann on

Eine weitere Version des RelayCommand

Hier eine generische Version des RelayCommand, die etwas typsicher ist.

  public class RelayCommand<TExecute, TCanExecute> : ICommand {

        private Action<TExecute> _execute;
        private Func<TCanExecute, bool> _canExecute;

        public RelayCommand(Action<TExecute> execute, Func<TCanExecute, bool> canExecute) {
            _canExecute = canExecute;
            _execute = execute;
        }

        public event EventHandler CanExecuteChanged {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public bool CanExecute(TCanExecute parameter) {
            return _canExecute(parameter);
        }

        public void Execute(TExecute parameter) {
            _execute(parameter);
        }

        public bool CanExecute(object parameter) {
            return CanExecute((TCanExecute)parameter);
        }

        public void Execute(object parameter) {
            Execute((TExecute)parameter);
        }
    }

Etwas WPF

Manuela Erdmann on

Der CanExecuteUpdateTimer

Leider sind dem CommandManager auch Grenzen gesetzt, nicht immer bemerkt die WPF Engine die Änderungen an der Oberfläche. Wenn zum Beispiel der Focus der Anwendung verloren geht, kann es in manchen Fällen sein, das die CanExecute Methoden durch den CommandManager nicht ausgeführt werden. Eine Lösung um sicherzustellen das die Controls synchron mit dem Ergebnis der CanExecute Methode bleiben ist ein DispatcherTimer. Ich habe hier ein gekapselten DispatchrTimer in der CanExecuteUpdateTimer Klasse, der in einem Zeitintervall, den CommandManager über die Methode InvalidateRequerySuggested mitteilt das er alle registrierten Commands auf ihre CanExecute Ergebnisse überprüfen soll.

 public class CanExecuteUpdateTimer {

        private DispatcherTimer _timer;

        public CanExecuteUpdateTimer(Dispatcher dispatcher, TimeSpan update) {
            _timer = new DispatcherTimer(DispatcherPriority.Background, dispatcher);
            _timer.Interval = update;
            _timer.Tick += (obj, args) => {
                CommandManager.InvalidateRequerySuggested();
            };
        }

        public void Start() {
            _timer.IsEnabled = true;
        }

        public void Stop() {
            _timer.IsEnabled = false;
        }
    }

Die CanExecuteUpdateTimer Klasse kann in der App.cs instanziiert werden. Zum Beispiel in der App.Main() Methode, nachdem die App Klasse instanziiert worden ist, kann man sich aus ihr auch den benötigten Dispatcher holen, der als Konstruktor Argument für die CanExecuteUpdateTimer Klasse benötigt wird.

Etwas WPF

manuela Erdmann on

Design-Time Instanzen

Hallo, hier habe ich ein kleinen Tipp. Wenn man viel in XAML arbeitet, kommt man oft in die Lage das die zu bindenden Member nicht zu finden sind bzw. zur Design-Time nicht erkannt werden. Darum kann man im DataContext eine nur zur Design-Time bestehende Ressource bzw. Instanz des ViewModels angeben. Das Ganze geht rein deklarativ in XAML! Und nicht nur für die ViewModels.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow"
        d:DataContext="{d:DesignData Source=DesignTimeViewModel.xaml}">
 
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock x:Name="TextBlock" Text="{Binding SampleBindingText}" Grid.Column="0" Grid.Row="0"></TextBlock>
    </Grid>
</Window>

<local:SampleViewModel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:WpfApplication1"
                    xmlns:system="clr-namespace:System;assembly=mscorlib">
    <local:SampleViewModel.SampleBindingText>
        <system:String>Test Design Time value</system:String>
    </local:SampleViewModel.SampleBindingText>
</local:SampleViewModel>

Bei einer ViewModel Resource deklariert man die ViewModel in einer XAML File und kann da auch den public Properties werte zuweisen, die nur in der Design-Time vorhanden sind und zur Design-Time angezeigt werden können, wenn an diese Properties gebunden wird.

Die andere Variante ist nur eine Instanz des ViewModels ohne extra values.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:wpfApplication1="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow"        
        d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True,Type=wpfApplication1:SampleViewModel}">
 
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock x:Name="TextBlock" Text="{Binding SampleBindingText}" Grid.Column="0" Grid.Row="0"></TextBlock>
    </Grid>
</Window>

Beide Varianten benötigen einen parameterlosen Konstruktor der aufrufbar ist, internal oder public.

Contact!