2010-04-21 20 views
5

Seit einigen Monaten verwende ich erfolgreich David Justices Default Button example in meiner SL 3 App. Dieser Ansatz basiert auf einer angefügten Eigenschaft.Silverlight 4 Standard Button Service

Nach dem SL4 Upgrade der Ansatz funktioniert nicht mehr, und ich eine XAML Ausnahme erhalten:

Unknown parser error: Scanner 2148474880

Hat jemand erfolgreich verwendet (oder anderes) Standardschaltfläche angebracht Verhalten in SL4?

Gibt es eine andere Möglichkeit, Standardschaltflächenverhalten in SL4 mit den neuen verfügbaren Klassen zu erreichen?

Danke, Mark

Antwort

2

I, indem Sie einen benutzerdefinierten Schlüssel Davids Ansatz erweitert (voreingestellt auf Enter) in einer zusätzlichen Eigenschaft festgelegt werden:

public static DependencyProperty ButtonKeyProperty = DependencyProperty.RegisterAttached(
     "ButtonKey", 
     typeof(Key), 
     typeof(Defaults), 
     new PropertyMetadata(Key.Enter, ButtonChanged)); 

    public static void SetButtonKey(DependencyObject dependencyObj, Key key) 
    { 
     dependencyObj.SetValue(ButtonKeyProperty, key); 
    } 

    public static Key GetButtonKey(DependencyObject dependencyObj) 
    { 
     return (Key)dependencyObj.GetValue(ButtonKeyProperty); 
    } 

I die ursprüngliche Eigenschaft geändert, um diese Eigenschaft dann zu nutzen:

Key key = GetButtonKey(dependencyObj); 
    if (button.IsEnabled && keyEvent.Key == key) 
     ... 

So, jetzt zum Beispiel kann ich Flucht als Schlüssel verwenden, wenn ich (Anmerkung mir den von den Klassen Namen geändert und Eigenschaften) will:

... UI:Defaults.Button="{Binding ElementName=myButton}" UI:Defaults.ButtonKey="Escape" ... 
3

ich wirklich hatte gehofft, dass es eine aus der Box Lösung für eine solche gemeinsame Anwendungsfall in Silverlight 4, ich glaube sein würde, aber leider nicht da ist.

Es gibt eine andere Standard-Button-Implementierung von Patrick Cauldwell. Er verwendet auch angehängte Eigenschaften.

Ich habe dies in einer SL 4-Anwendung getestet und es scheint die Aufgabe zu erledigen.

Sie den Code finden Sie hier: http://www.cauldwell.net/patrick/blog/DefaultButtonSemanticsInSilverlightRevisited.aspx

Edit: I David Justice Code gezwickt haben, um es für Silverlight 4. Ich habe Arbeit zu bekommen verändert nur die GetDefaultButton und SetDefaultButton zu nehmen und Rückkehr ein DefaultButtonService. Die Verwendung ist die gleiche wie auf seiner Website angegeben. Dies sollte für Sie arbeiten:

Edit2: Added XAML Beispiel für Klarheit.

public class DefaultButtonService 
    { 
     public static DependencyProperty DefaultButtonProperty = 
      DependencyProperty.RegisterAttached("DefaultButton", 
               typeof(Button), 
               typeof(DefaultButtonService), 
               new PropertyMetadata(null, DefaultButtonChanged)); 

     private static void DefaultButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      var uiElement = d as UIElement; 
      var button = e.NewValue as Button; 
      if (uiElement != null && button != null) 
      { 
       uiElement.KeyUp += (sender, arg) => 
       { 
        if (arg.Key == Key.Enter) 
        { 
         var peer = new ButtonAutomationPeer(button); 
         var invokeProv = 
          peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider; 
         if (invokeProv != null) 
          invokeProv.Invoke(); 
        } 
       }; 
      } 
     } 

     public static DefaultButtonService GetDefaultButton(UIElement obj) 
     { 
      return (DefaultButtonService)obj.GetValue(DefaultButtonProperty); 
     } 

     public static void SetDefaultButton(DependencyObject obj, DefaultButtonService button) 
     { 
      obj.SetValue(DefaultButtonProperty, button); 
     }   
    } 

Wie in XAML anwenden:

<StackPanel> 
    <TextBox DinnerConfig:DefaultButtonService.DefaultButton="{Binding ElementName=MyButton}" 
       Text="Press Enter" /> 
    <Button x:Name="MyButton" 
      Content="Click me" /> 
</StackPanel> 
+0

Vielen Dank. David's und Patricks Ansätze sind ziemlich genau die gleichen - obwohl ich mich freue zu sehen, dass das Problem nicht mit SL4 ist, muss ein bestimmtes Szenario mit unserer App verbunden sein. Danke, dass Sie sich Zeit genommen haben, uns zu antworten. +1 –

+0

Sollte die "Get/SetDefaultButton" -Methode nicht einen ButtonButtonService zurückgeben? Der fragliche Typ ist der Typ des tatsächlichen Werts, der in der Eigenschaft abgerufen/gespeichert wird. Ich habe diese Änderung selbst vorgenommen und es funktioniert jetzt. – Trinition

+0

Ja, Trinition, Sie haben Recht. Wenn Sie ein Beispiel hinzufügen möchten, stimme ich Ihrer Antwort zu. Sie können mein von unten hinzugefügtes Beispiel kopieren, wenn Sie möchten. –

0

Das Problem wird durch eine schlecht getippt GetDefaultButton Methode verursacht wurde. Dies sollte als Button, getippt wurden zum Beispiel mit:

public static Button GetDefaultButton(UIElement obj) 
    { 
     return (Button)obj.GetValue(DefaultButtonProperty); 
    } 

statt

public static DefaultButtonService GetDefaultButton(UIElement obj)  
    {  
     return (DefaultButtonService)obj.GetValue(DefaultButtonProperty);  
    } 

funktioniert wie erwartet.

HTH jemand anderes,
Mark

8

Die endgültige Lösung für uns war auch, um das Problem zu bekommen, wo die Träger Eigenschaft wurde nicht vor dem Button-Klick auftritt (wie in allen MVVM Muster) aktualisiert werden .. .. Hinweis:peer.SetFocus();

Edit: Added XAML Beispiel.

public static class DefaultButtonService 
{ 
    public static DependencyProperty DefaultButtonProperty = 
      DependencyProperty.RegisterAttached("DefaultButton", 
               typeof(Button), 
               typeof(DefaultButtonService), 
               new PropertyMetadata(null, DefaultButtonChanged)); 

    private static void DefaultButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { 
     var uiElement = d as UIElement; 
     var button = e.NewValue as Button; 
     if (uiElement != null && button != null) { 
      uiElement.KeyUp += (sender, arg) => { 
       var peer = new ButtonAutomationPeer(button); 

       if (arg.Key == Key.Enter) { 
        peer.SetFocus(); 
        uiElement.Dispatcher.BeginInvoke((Action)delegate { 

         var invokeProv = 
          peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider; 
         if (invokeProv != null) 
          invokeProv.Invoke(); 
        }); 
       } 
      }; 
     } 

    } 

    public static Button GetDefaultButton(UIElement obj) { 
     return (Button)obj.GetValue(DefaultButtonProperty); 
    } 

    public static void SetDefaultButton(DependencyObject obj, Button button) { 
     obj.SetValue(DefaultButtonProperty, button); 
    }  
} 

Wie in XAML anwenden:

<StackPanel> 
    <TextBox DinnerConfig:DefaultButtonService.DefaultButton="{Binding ElementName=MyButton}" 
       Text="Press Enter" /> 
    <Button x:Name="MyButton" 
      Content="Click me" /> 
</StackPanel> 
0

Hier ist eine einfache Möglichkeit, eine Standard-Schaltfläche verdrahten, wenn Eingabe gedrückt wird:

Aus Sicherheitsgründen Silverlight finden Sie eine nicht zulassen, rufen button handler direkt in code, so dass wir eine neue routine erstellen müssen, die aufgerufen werden kann, und dann die button handler und die form keydown handler diese routine aufrufen.

Schritt 1: eine Routine machen und alles darin setzen, dass die Taste Routine 2

private void DoSharedRoutine(){ // do something } 

Schritt hatte: Schaltfläche Handler Aufruf haben 3

private void Login_Click(object sender, System.Windows.RoutedEventArgs e) 
    { 
     DoSharedRoutine(); 
    } 

Schritt Routine geteilt: haben keyDown Handler Ihr Panel, das Ihre Taste enthält, rufen Sie die gemeinsame Routine auf

private void MyGrid_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) 
    { 
     if (e.Key == Key.Enter) DoSharedRoutine(); 
    }