幾個月來,我一直在我的SL 3應用程序中成功使用David Justices Default Button example。這種方法基於附屬性。Silverlight 4默認按鈕服務
升級到SL4後,該方法不再起作用了,我得到一個XAML例外:
Unknown parser error: Scanner 2148474880
有沒有人成功地使用這個(或任何其他)在SL4默認按鈕附加的行爲?
有沒有其他的方式來實現SL4中的默認按鈕行爲與新的類可用?
謝謝, 馬克
幾個月來,我一直在我的SL 3應用程序中成功使用David Justices Default Button example。這種方法基於附屬性。Silverlight 4默認按鈕服務
升級到SL4後,該方法不再起作用了,我得到一個XAML例外:
Unknown parser error: Scanner 2148474880
有沒有人成功地使用這個(或任何其他)在SL4默認按鈕附加的行爲?
有沒有其他的方式來實現SL4中的默認按鈕行爲與新的類可用?
謝謝, 馬克
我伸出大衛的做法,允許自定義鍵(默認爲輸入)的一個附加屬性進行設置:
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);
}
我修改原來的財產,然後利用此屬性:
Key key = GetButtonKey(dependencyObj);
if (button.IsEnabled && keyEvent.Key == key)
...
所以現在,例如,我可以使用轉義爲關鍵,如果我想(注意,我改變了命名的種類和屬性):
... UI:Defaults.Button="{Binding ElementName=myButton}" UI:Defaults.ButtonKey="Escape" ...
我真的很希望會有一個開箱即用解決方案的這種共同的用例在Silverlight 4中,但不幸的是,我不覺得有什麼。
Patrick Cauldwell還有另一個默認按鈕實現。他也在使用附加屬性。
我已經在SL 4應用程序中測試過它,它似乎完成了這項工作。
您可以在這裏找到代碼: http://www.cauldwell.net/patrick/blog/DefaultButtonSemanticsInSilverlightRevisited.aspx
編輯: 我已經調整了大衛正義的代碼來得到它的工作爲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>
的問題是由輸入不佳GetDefaultButton
方法造成的。這本來是類型爲Button
,例如使用:的
public static Button GetDefaultButton(UIElement obj)
{
return (Button)obj.GetValue(DefaultButtonProperty);
}
代替
public static DefaultButtonService GetDefaultButton(UIElement obj)
{
return (DefaultButtonService)obj.GetValue(DefaultButtonProperty);
}
按預期工作。
HTH別人,
馬克
對我們來說,最終的解決方案還必須得到解決,其中後備財產沒有被之前的按鈕,點擊發生的歷史(如在所有的MVVM模式)更新的問題.. .. 注:peer.SetFocus();
編輯: 新增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>
這裏是進入被按下時,連接一個默認的按鈕,一個簡單的方法:
出於安全原因,Silverlight將不會讓你叫按鈕處理程序直接在代碼中,所以我們必須創建一個可以調用的新例程,然後讓按鈕處理程序和表單keydown處理程序都調用此例程。
第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();
}
謝謝。大衛和帕特里克的方法幾乎完全一樣 - 雖然我很高興看到這個問題不在SL4中,但是我們的應用程序必須有一個特定的場景。感謝您花時間回覆+1 – 2010-04-29 11:31:48
「Get/SetDefaultButton」方法不應該返回/取得一個Button而不是DefaultButtonService嗎?有問題的類型是正在檢索/存儲在屬性中的實際值的類型。我自己做了這個改變,現在它正在工作。 – Trinition 2010-05-26 13:58:43
是的,Trinition,你是對的。如果你想添加一個例子,我會投票你的答案是正確的。如果您願意,可以複製我從下面添加的示例。 – 2010-05-28 11:11:27