Silverlight 4.0 Silverlight 4默认按钮服务
几个月来,我一直在成功地使用我的SL 3应用程序。此方法基于附加属性 升级到SL4后,该方法不再有效,我得到一个XAML异常: 未知分析器错误:扫描仪2148474880 是否有人成功地在SL4中使用了此(或任何其他)默认按钮连接行为 在SL4中,有没有其他方法可以通过新的可用类实现默认按钮行为 谢谢,Silverlight 4.0 Silverlight 4默认按钮服务,silverlight-4.0,attached-properties,defaultbutton,Silverlight 4.0,Attached Properties,Defaultbutton,几个月来,我一直在成功地使用我的SL 3应用程序。此方法基于附加属性 升级到SL4后,该方法不再有效,我得到一个XAML异常: 未知分析器错误:扫描仪2148474880 是否有人成功地在SL4中使用了此(或任何其他)默认按钮连接行为 在SL4中,有没有其他方法可以通过新的可用类实现默认按钮行为 谢谢, Mark我真的希望Silverlight 4中有一个现成的解决方案来解决这样一个常见的用例,但不幸的是,我认为没有 Patrick Cauldwell还实现了另一个默认按钮。他还使用附加属性 我
Mark我真的希望Silverlight 4中有一个现成的解决方案来解决这样一个常见的用例,但不幸的是,我认为没有 Patrick Cauldwell还实现了另一个默认按钮。他还使用附加属性 我已经在一个SL 4应用程序中测试过了,它似乎可以胜任这项工作 您可以在此处找到代码: 编辑: 我修改了David Justice的代码,使其在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>
<StackPanel>
<TextBox DinnerConfig:DefaultButtonService.DefaultButton="{Binding ElementName=MyButton}"
Text="Press Enter" />
<Button x:Name="MyButton"
Content="Click me" />
</StackPanel>
我扩展了David的方法,允许在附加属性中设置自定义键(默认输入):
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)
...
我修改了原始属性以利用此属性:
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)
...
例如,现在,如果需要,我可以使用Escape作为键(注意,我更改了类和属性的名称):
该问题是由键入错误的
GetDefaultButton
方法引起的。应将其键入为按钮
,例如,使用:
public static Button GetDefaultButton(UIElement obj)
{
return (Button)obj.GetValue(DefaultButtonProperty);
}
而不是
public static DefaultButtonService GetDefaultButton(UIElement obj)
{
return (DefaultButtonService)obj.GetValue(DefaultButtonProperty);
}
一切正常
其他人,Mark我们的最终解决方案还必须绕过在按钮点击发生之前未更新备份属性的问题(与所有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>
<StackPanel>
<TextBox DinnerConfig:DefaultButtonService.DefaultButton="{Binding ElementName=MyButton}"
Text="Press Enter" />
<Button x:Name="MyButton"
Content="Click me" />
</StackPanel>
按下enter键时,这里有一种连接默认按钮的简单方法:
出于安全原因,silverlight不允许您在代码中直接调用按钮处理程序,因此我们必须创建一个可以调用的新例程,然后让按钮处理程序和表单keydown处理程序都调用此例程
第1步:做一个例程,把按钮例程拥有的所有东西都放进去
private void DoSharedRoutine(){ // do something }
步骤2:让按钮处理程序调用共享例程
private void Login_Click(object sender, System.Windows.RoutedEventArgs e)
{
DoSharedRoutine();
}
private void MyGrid_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == Key.Enter) DoSharedRoutine();
}
步骤3:让包含按钮的面板的按键处理程序调用共享例程
private void Login_Click(object sender, System.Windows.RoutedEventArgs e)
{
DoSharedRoutine();
}
private void MyGrid_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == Key.Enter) DoSharedRoutine();
}
谢谢David和Patrick的方法几乎完全相同——尽管我很高兴看到问题不在SL4,而一定是与我们的应用程序相关的特定场景。感谢您花时间回复+1“Get/SetDefaultButton”方法不应该返回/获取按钮而不是DefaultButton服务吗?所讨论的类型是在属性中检索/存储的实际值的类型。我自己做了改变,现在起作用了。是的,Trinition,你是对的。如果你想添加一个例子,我会投票认为你的答案是正确的。如果您愿意,您可以复制我从下面添加的示例。