In der Praxis kann es vorkommen, dass gebundene Eigenschaften mal nicht eben einen Wert zurück liefern, sondern durchaus länger benötigen. Dies tritt beispielsweise auf, wenn

  • Images (oder Listen davon) geladen werden
  • Daten von einem Service abgeholt werden
  • Längere Berechnungen durchzuführen sind

Sicherlich ließen sich weitere Punkte finden. Jetzt wäre es jedoch für den Benutzer unangenehm, die Oberfläche zu sperren und ihm keine Rückmeldung zu liefern, dass gerade seine Anforderung ausgeführt wird. Um dies zu bewerkstelligen, gibt es seit je her PriorityBinding. Darüber können mehrere Bindungen inklusive Priorität festgelegt werden. Die Priorität wird dabei in der Reihenfolge der Bindungs-Angaben bestimmt. Die erste Bindung hat die höchste Priorität.

Beispiele zum Thema PriorityBinding gibt es einige. Die meisten arbeiten jedoch mit einem Thread.Sleep und sind gerade für Einsteiger daher nicht so einfach auf die Realität um zu legen. Das nachfolgend gezeigte Beispiel folgt zwar ebenso einem akademischen Ansatz, kommt jedoch ohne Thread.Sleep aus und sollte die Funktionsweise daher – hoffentlich – besser beschreiben.

Beispiel

Die hier gezeigte Anwendung bietet die Möglichkeit, einen Wert einzugeben, auf dessen Basis der letzte Wert der Fibonacci-Reihe errechnet wird. Ausgeführt wird die Berechnung, wenn auf die angebotene Schaltfläche geklickt wird. Die nachfolgende Abbildung zeigt die sehr einfache Oberfläche. Während der Berechnung soll der Anwender als Resultat eine Meldung erhalten, dass die Berechnung in Gange ist bzw. schlussendlich das tatsächliche Ergebnis.

image

Implementierung

Zu Grunde liegt dieser Anwendung die von mir bereits in mehreren Artikeln angesprochene MVVM-Implementierung. D.h. es wird versucht, an dieser Stelle eine saubere Auftrennung der Zuständigkeiten zu erreichen.

Die Bereitstellung der notwendigen Eigenschaften, Berechnungen und Aktionen (siehe Command) übernimmt ein ViewModel:

#f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
#f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
[LocatorAttribute("MainViewModel")]

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">#0000ff">public #0000ff">class MainViewModel : ViewModelBase

{

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff">private #0000ff">string calculationMessage = "Calculating result ...";

    #0000ff">private #0000ff">int inputValue;

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff">private RelayCommand calculateCommand;

 

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff">public #0000ff">string CaluculationMessage

    {

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        get { #0000ff">return calculationMessage; }

    }

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> 

    #0000ff">public #0000ff">int InputValue

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    {

        get { #0000ff">return inputValue; }

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        set

        {

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">            #0000ff">if (inputValue == #0000ff">value)

                #0000ff">return;

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">            inputValue = #0000ff">value;

            RaisePropertyChanged("InputValue");

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        }

    }

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> 

    #0000ff">public #0000ff">int Result

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    {

        get { #0000ff">return CalcFibonacci(InputValue); }

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    }

 

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff">private #0000ff">int CalcFibonacci(#0000ff">int x)

    {

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        #0000ff">if (x <= 1)

        {

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">            #0000ff">return 1;

        }

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        #0000ff">return CalcFibonacci(x - 1) + CalcFibonacci(x - 2);

    }

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> 

    #0000ff">public ICommand CalculateCommand

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    {

        get

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        {

            #0000ff">if (calculateCommand == #0000ff">null)

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">                calculateCommand = #0000ff">new RelayCommand(Calculate);

            #0000ff">return calculateCommand;

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        }

    }

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> 

    #0000ff">private #0000ff">void Calculate(#0000ff">object param)

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    {

        RaisePropertyChanged("CaluculationMessage");

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        RaisePropertyChanged("Result");

    }

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">}

Die Eigenschaft CalculationMessage liefert einen String zurück, der anzeigt, dass die Berechnung aktuell in Gange ist. Result selbst ruft eine Methode auf, welche den Fibonacci berechnet und das Ergebnis zurück liefert. Diese Berechnung kann nun, abhängig vom Eingangswert, recht lange dauern. Der implementierte und nach aussen gegebene Command löst lediglich ein PropertyChanged der beschriebenen Eigenschaften aus (dadurch wird beim Aktualisierung der Bindung auch die Berechnung durchgeführt).

Nun werfen wir einen Blick auf die View:

#f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
#f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
#0000ff"><Grid#0000ff">>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff"><Grid.ColumnDefinitions#0000ff">>

        #0000ff"><ColumnDefinition #ff0000">Width#0000ff">="Auto"#0000ff">/>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        #0000ff"><ColumnDefinition #ff0000">Width#0000ff">="*"#0000ff">/>

    #0000ff"></Grid.ColumnDefinitions#0000ff">>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff"><Grid.RowDefinitions#0000ff">>

        #0000ff"><RowDefinition #ff0000">Height#0000ff">="Auto"#0000ff">/>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        #0000ff"><RowDefinition #ff0000">Height#0000ff">="Auto"#0000ff">/>

        #0000ff"><RowDefinition #ff0000">Height#0000ff">="Auto"#0000ff">/>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        #0000ff"><RowDefinition #ff0000">Height#0000ff">="Auto"#0000ff">/>

        #0000ff"><RowDefinition #ff0000">Height#0000ff">="Auto"#0000ff">/>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff"></Grid.RowDefinitions#0000ff">>

 

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff"><TextBlock #ff0000">Text#0000ff">="PriorityBinding Sample" 

                #ff0000">Style#0000ff">="{StaticResource HeaderBlockStyle}" 

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">                #ff0000">Grid.#ff0000">ColumnSpan#0000ff">="2"#0000ff">/>

        

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff"><TextBlock #ff0000">Text#0000ff">="Fib of" #ff0000">Grid.#ff0000">Row#0000ff">="2"#0000ff">/>

    #0000ff"><StackPanel #ff0000">Orientation#0000ff">="Horizontal" #ff0000">Grid.#ff0000">Row#0000ff">="2" #ff0000">Grid.#ff0000">Column#0000ff">="1"#0000ff">>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        #0000ff"><TextBox #ff0000">Text#0000ff">="{Binding InputValue}"#0000ff">/>    

        #0000ff"><TextBlock #ff0000">Text="#ff0000">Enter #ff0000">at #ff0000">least #ff0000">a #ff0000">value #0000ff">> 30"#0000ff">/>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff"></StackPanel#0000ff">>

        

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff"><TextBlock #ff0000">Text#0000ff">="Result" #ff0000">Grid.#ff0000">Row#0000ff">="3"#0000ff">/>

    #0000ff"><TextBlock #ff0000">Grid.#ff0000">Column#0000ff">="1" #ff0000">Grid.#ff0000">Row#0000ff">="3"#0000ff">>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        #0000ff"><TextBlock.Text#0000ff">>

            #0000ff"><PriorityBinding#0000ff">>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">                #0000ff"><Binding #ff0000">Path#0000ff">="Result" #ff0000">IsAsync#0000ff">="True" #ff0000">Mode#0000ff">="OneWay"#0000ff">/>

                #0000ff"><Binding #ff0000">Path#0000ff">="CaluculationMessage" #ff0000">Mode#0000ff">="OneWay"#0000ff">/>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">            #0000ff"></PriorityBinding#0000ff">>

        #0000ff"></TextBlock.Text#0000ff">>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff"></TextBlock#0000ff">>

        

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff"><Button #ff0000">Content#0000ff">="Calculate" 

            #ff0000">Command#0000ff">="{Binding CalculateCommand}" 

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">            #ff0000">Grid.#ff0000">Row#0000ff">="4" 

            #ff0000">Grid.#ff0000">ColumnSpan#0000ff">="2"#0000ff">/>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">#0000ff"></Grid#0000ff">>

Von besonderer Bedeutung ist hier das TextBlock-Element, welches für die Darstellung des Ergebnisses zuständig ist:

#f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
#f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
#0000ff"><TextBlock #ff0000">Grid.#ff0000">Column#0000ff">="1" #ff0000">Grid.#ff0000">Row#0000ff">="3"#0000ff">>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    #0000ff"><TextBlock.Text#0000ff">>

        #0000ff"><PriorityBinding#0000ff">>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">            #0000ff"><Binding #ff0000">Path#0000ff">="Result" #ff0000">IsAsync#0000ff">="True" #ff0000">Mode#0000ff">="OneWay"#0000ff">/>

            #0000ff"><Binding #ff0000">Path#0000ff">="CaluculationMessage" #ff0000">Mode#0000ff">="OneWay"#0000ff">/>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        #0000ff"></PriorityBinding#0000ff">>

    #0000ff"></TextBlock.Text#0000ff">>

#f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">#0000ff"></TextBlock#0000ff">>

Hier wird für die Eigenschaft Text ein PriorityBinding angegeben. Die höchste Priorität besitzt die Bindung an die Eigenschaft Result des ViewModels. Diese Bindung erfolgt asynchron (da sie etwas länger dauern kann). Die zweite Bindung erfolgt auf unsere Eigenschaft, welche rückmeldet, dass der Berechnungsvorgang in Arbeit ist.

Geben wir in der ausgeführten Anwendung einen größeren Wert ein, liefert das erste Binding beim ersten Zugriff keinen Wert zurück. Daher wird das nächste Binding in der Liste herangezogen. Dieses liefert sofort einen Wert zurück (es muss nur ein String zurück gegeben werden). Steht das Ergebnis zur Verfügung, wird dieses nachgereicht und die Statusmeldung verschwindet.

Hinweis: DependencyProperty.UnsetValue gilt nicht als erfolgreicher Rückgabewert.

Es besteht auch noch die Möglichkeit die Eigenschaft FallbackValue der PriorityBinding zu setzen. Dies würde den Weg über die zusätzliche Eigenschaft im ViewModel sparen. Wer jedoch mehr Kontrolle über den angezeigten Wert benötigt, wird den gezeigten Weg wählen.

Download

Dieses Beispiel steht untenstehend als Download zur Verfügung.

Über den Autor

Norbert Eder

Ich bin ein leidenschaftlicher Softwareentwickler und Fotograf. Mein Wissen und meine Gedanken teile ich nicht nur hier im Blog, sondern auch in Fachartikeln und Büchern.

Cookie-Einstellungen
Auf dieser Website werden Cookie verwendet. Diese werden für den Betrieb der Website benötigt oder helfen uns dabei, die Website zu verbessern.
Alle Cookies zulassen
Auswahl speichern
Individuelle Einstellungen
Individuelle Einstellungen
Dies ist eine Übersicht aller Cookies, die auf der Website verwendet werden. Sie haben die Möglichkeit, individuelle Cookie-Einstellungen vorzunehmen. Geben Sie einzelnen Cookies oder ganzen Gruppen Ihre Einwilligung. Essentielle Cookies lassen sich nicht deaktivieren.
Speichern
Abbrechen
Essenziell (1)
Essenzielle Cookies werden für die grundlegende Funktionalität der Website benötigt.
Cookies anzeigen