几个月来,我一直在我的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