2016-10-05 2 views
0

Ich habe einen Text ausgeführt werden, befehlen konnte, die wie folgt auf einen Befehl gebunden ist:Benutzer benachrichtigen, die nicht

<TextBox Text="{Binding Path=TextContent, UpdateSourceTrigger=PropertyChanged}"> 
     <TextBox.InputBindings> 
      <KeyBinding Command="{Binding Path=MyCommand}" Key="Enter" /> 
     </TextBox.InputBindings> 
</TextBox> 

Die Eigenschaft TextContent eine Zeichenfolge im Ansichtsmodell definiert ist. Der Befehl MyCommand ist ebenfalls im ViewModel definiert. Das ViewModel kennt die Ansicht nicht.

Der Befehl wird aufgerufen, wenn die TextBox den Fokus hat und die Eingabetaste gedrückt wird. Wenn CanExecute den Wert false zurückgibt, kann der Benutzer leider (visuell) nicht sehen, dass der Befehl nicht ausgeführt wurde, da es keine sichtbare Änderung in der TextBox gibt.

Ich suche Ratschläge, wie man dem Benutzer zeigt, dass der Befehl nicht ausgeführt werden konnte, nachdem er Enter gedrückt hatte.

Meine Ideen (und meine Zweifel an ihnen):

  • Deaktivieren der TextBox wenn CanExecute kehrt false: Das ist keine Option, da der Rückgabewert von CanExecute jedesmal, wenn ein Brief geschrieben wird ändern können/geändert (der Text in der TextBox beeinflusst das Ergebnis von CanExecute). Wenn es zum ersten Mal deaktiviert wird, kann der Benutzer nicht mehr hinein tippen, sodass es für immer deaktiviert bleibt.

  • Ein Meldungsfeld anzeigen, dass der Befehl nicht ausgeführt wurde: Denken Sie daran, dass ViewModel die Ansicht nicht kennt. Ist es sogar möglich, eine Message Box vom ViewModel aus zu öffnen? Außerdem, wo sollte ich den Anruf zum Öffnen einer Nachrichtenbox setzen? Nicht innerhalb CanExecute, weil ich nur das Meldungsfeld nach dem Eingeben erhalten möchte, nicht immer CanExecutefalse zurückgibt. Vielleicht make CanExecute immer true zurückgeben und die Checks innerhalb Execute: Wenn Schecks in Ordnung sind, tun Sie den Befehl Zeug, wenn nicht, zeigen Sie eine Nachricht an den Benutzer. Aber dann ist der Punkt CanExecute zu haben, ist völlig verfehlt ...

Ich möchte MVVM halten, aber einige Code-Behind für Sachen auf die Ansichtsmodell Umleitung scheint für mich in Ordnung.

+0

In Bezug auf das Anzeigen von Meldungsfeldern aus dem 'View Model' können Sie einen ** service ** orientierten Ansatz verwenden, bei dem Sie eine Meldungsfeld-Serviceklasse injizieren können, die von Ihrem Ansichtsmodell zum Anzeigen von Meldungsfeldern verwendet werden kann. Dadurch wird sichergestellt, dass Ihr Ansichtsmodell dem MVVM-Muster entspricht. Ich habe eine kleine Bibliothek geschrieben, die das auf [GitHub] (https://github.com/mike-eason/MessageBoxAbstraction) tut. –

Antwort

1

Ich schlage die folgende Lösung vor.

Hier ist ein Beispiel, wie der Benutzer, an dem ich gerade arbeite, benachrichtigt wird.

Ich möchte der Benutzer ein Datenlimit eingeben, die vom Typ Int, Double oder String ist. Es soll also der Benutzertyp im richtigen Typ überprüft werden. Ich verwende eine Eigenschaft ValidateLimits, die die Zeichenfolge MyLimits in Ihrem Fall TextContent überprüft.

Jedes Mal, wenn der Benutzer etwas in die TextBox eingibt, überprüft ValidateLimits die Zeichenfolge. Wenn es keine gültige Zeichenfolge im Textfeld ist, geben Sie false zurück, andernfalls true zurück. Wenn false, dann markieren Sie es mit dem DataTrigger, indem Sie einige Eigenschaften für die TextBox festlegen, die in meinem Fall einige Border- und Foreground-Farben sind, auch eine QuickInfo.

Auch in Ihrem Fall möchten Sie Ihre Validate-Methode in Ihrer CanExecute Methode aufrufen.

Wenn Sie bereits eine Funktion haben, um zu überprüfen, ob der Befehl in Ordnung ist, fügen Sie ihn einfach zur DataTrigger-Bindung hinzu. ein Objekt bool IsCommandExecuted in Ihrer Command Klasse

<TextBox Text="{Binding MyLimit1, UpdateSourceTrigger=PropertyChanged}" Margin="-6,0,-6,0"> 
    <TextBox.Style> 
    <Style TargetType="TextBox"> 
    <!-- Properties that needs to be changed with the data trigger cannot be set outside the style. Default values needs to be set inside the style --> 
    <Setter Property="ToolTip" Value="{Binding FriendlyCompareRule}"/> 
     <Style.Triggers> 
     <DataTrigger Binding="{Binding ValidateLimits}" Value="false"> 
      <Setter Property="Foreground" Value="Red"/> 
      <Setter Property="BorderBrush" Value="Red"/> 
      <Setter Property="BorderThickness" Value="2"/> 
      <Setter Property="ToolTip" Value="Cannot parse value to correct data type"/> 
     </DataTrigger> 
     </Style.Triggers> 
    </Style> 
    </TextBox.Style> 

public bool ValidateLimits 
{ 
    get 
    { 
    // Check if MyLimit1 is correct data type 
    return true/false; 
    } 
} 
0

Verwendung. Legen Sie diese Eigenschaft entsprechend fest.

ein ToolTip verwenden und binden ihre IsOpen Eigenschaft IsCommandExecuted Eigenschaft wie folgt:

<TextBox ...> 
    <TextBox.ToolTip> 
     <ToolTip IsOpen="{Binding MyCommand.IsCommandExecuted}">...</ToolTip> 
    </TextBox.ToolTip> 
</TextBox> 

Dieses Konzept erklärt, ändern sich entsprechend.

Verwandte Themen