2010-04-21 3 views
5

В течение нескольких месяцев я успешно использовал David Justices Default Button example в своем приложении SL 3. Этот подход основан на присоединенном свойстве. неSilverlight 4 Служба кнопки по умолчанию

После обновления до SL4 подход больше не работает, и я получаю исключение XAML:

Unknown parser error: Scanner 2148474880

Кто успешно использовал этот (или любые другие) кнопку по умолчанию присоединенных поведений в SL4?

Есть ли другой способ добиться поведения кнопки по умолчанию в SL4 с новыми доступными классами?

Спасибо, Марк

ответ

2

Я расширенный подход Дэвида, позволяя пользовательский ключ (по умолчанию для Enter), чтобы установить в качестве дополнительного свойства:

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 модифицировало первоначальное имущество, чтобы воспользоваться этим преимуществом:

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

Так что теперь, к примеру, я могу использовать побег в качестве ключа, если я хочу (примечание я изменил имя классов и свойств):

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

Я действительно надеялся, что было бы из раствора коробки для такого общего потребительной случае в Silverlight 4, но, к сожалению, я не думаю, что есть.

Существует еще одна реализация кнопки «По умолчанию» Патрика Коулдуэлла. Он также использует Attached Properties.

Я тестировал это в приложении SL 4 и, похоже, выполнял эту работу.

Вы можете найти код здесь: http://www.cauldwell.net/patrick/blog/DefaultButtonSemanticsInSilverlightRevisited.aspx

Edit: Я подправили код Дэвид Джастис, чтобы получить его работу на Silverlight 4. Я только изменил GetDefaultButton и SetDefaultButton взять и возвращение DefaultButtonService. Использование такое же, как на его сайте. Это должно работать для вас:

edit2: пример Добавлена ​​XAML для ясности.

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); 
     }   
    } 

Как применять в XAML:

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

Спасибо. Подходы Дэвида и Патрика практически совпадают - хотя я рад видеть, что проблема не в SL4, должен быть конкретный сценарий, связанный с нашим приложением. Спасибо, что нашли время для ответа +1 –

+0

Не следует ли методам Get/SetDefaultButton возвращать/брать кнопку вместо функции DefaultButtonService? Тип, о котором идет речь, относится к типу фактического значения, которое извлекается/сохраняется в свойстве. Я сделал это изменение сам, и он работает сейчас. – Trinition

+0

Да, Trinition, вы правы. Если вы хотите добавить пример, я буду голосовать за ваш ответ правильно. Вы можете скопировать мой пример, добавленный снизу, если хотите. –

0

Проблема была вызвана плохо набранным GetDefaultButton методом. Это должно быть классифицирован как Button, например, с использованием:

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

вместо

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

работает, как ожидалось.

НТН кто-то еще,
Марк

8

Окончательным решения для нас также должны были обойти вопрос, где свойство поддержки не было обновлен до щелчка кнопки встречающегося (как и во всех моделях MVVM) .. .. Примечание:peer.SetFocus();

Edit: Добавлен XAML пример.

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); 
    }  
} 

Как применять в XAML:

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

Вот простой способ при входе нажатии телеграфировать кнопку по умолчанию:

По соображениям безопасности Silverlight не позволит вам назвать непосредственно в коде, поэтому мы должны создать новую подпрограмму, которая может быть вызвана, а затем обработчик кнопки и обработчик ключа формы вызывают эту процедуру.

Шаг 1: сделать рутинным и поставить все в нем, что рутина кнопка была

private void DoSharedRoutine(){ // do something } 

Шаг 2: есть кнопка вызов обработчика совместно рутина

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

Шаг 3: есть KeyDown обработчик ваша панель, содержащая вашу кнопку, вызывает общую процедуру.

private void MyGrid_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) 
    { 
     if (e.Key == Key.Enter) DoSharedRoutine(); 
    } 
Смежные вопросы