问题
I'm looking for a way to automatically set the initial focus on a Silverlight UserControl to a specific control. I have a login page with a user name textbox and I'd like to have it so that as soon as the user goes to the page their cursor is already positioned and waiting in the username textbox instead of having to make them click the box.
I tried calling .Focus in the UserControl's Loaded event but with no success. Anyone know how to do this?
回答1:
I whipped up a quick SL3 app and it is difficult to have the initial focus go to the UserControl let alone to a control within the Silverlight control.
However, see if this solution solves this issue for you. You'll have to use a little JavaScript.
Here's the code for reference:
<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls"
TagPrefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="height:100%;">
<head runat="server">
<title>Test Page For TextFocusTest</title>
<script type="text/javascript">
window.onload = function()
{
document.getElementById('Xaml1').focus();
}
</script>
</head>
<body style="height:100%;margin:0;">
<form id="form1" runat="server" style="height:100%;">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div style="height:100%;">
<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/TextFocusTest.xap" Version="2.0" Width="100%" Height="100%" />
</div>
</form>
</body>
</html>
Once your SL control has focus, you can further set the focus to a specific control using something like:
namespace SilverlightApplication2
{
public partial class MainPage : UserControl
{
public MainPage ()
{
InitializeComponent ();
this.GotFocus += new RoutedEventHandler (MainPage_GotFocus);
}
void MainPage_GotFocus (object sender, RoutedEventArgs e)
{
uxLogin.Focus ();
}
}
}
where uxLogin is defined in XAML as:
<TextBox x:Name="uxLogin" Height="25" Width="100" />
回答2:
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
HtmlPage.Plugin.Focus();
MyTextBox.Focus();
}
回答3:
If you want to do it in a PRISM or MVVM way (get rid of the code-behind code), you can implement a behavior. In my case I focus the view in the username field if it's empty and in the password if it's set (hence the 2 parameters).
My implementation:
public static class ControlTextFocusBehavior
{
public static readonly DependencyProperty FocusParameterProperty = DependencyProperty.RegisterAttached(
"FocusParameter",
typeof(string),
typeof(ControlTextFocusBehavior),
new PropertyMetadata(OnSetFocusParameterCallBack));
public static readonly DependencyProperty IsEmptyFocusedProperty = DependencyProperty.RegisterAttached(
"IsEmptyFocused",
typeof(bool),
typeof(ControlTextFocusBehavior),
new PropertyMetadata(true));
private static void OnSetFocusParameterCallBack(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
Control control = dependencyObject as Control;
if (control != null)
{
control.Loaded += new RoutedEventHandler(control_Loaded);
}
}
private static void control_Loaded(object sender, RoutedEventArgs e)
{
Control control = sender as Control;
control.Loaded -= new RoutedEventHandler(control_Loaded);
DependencyObject dependencyObject = sender as DependencyObject;
if (dependencyObject != null)
{
bool isEmptyFocused = GetIsEmptyFocused(dependencyObject);
bool isNullOrEmpty = string.IsNullOrEmpty(GetFocusParameter(dependencyObject));
if ((isEmptyFocused && isNullOrEmpty) ||
(!isEmptyFocused && !isNullOrEmpty))
{
HtmlPage.Plugin.Focus();
control.Focus();
}
}
}
public static void SetFocusParameter(DependencyObject dependencyObject, string parameter)
{
dependencyObject.SetValue(FocusParameterProperty, parameter);
}
public static string GetFocusParameter(DependencyObject dependencyObject)
{
return dependencyObject.GetValue(FocusParameterProperty) as string;
}
public static void SetIsEmptyFocused(DependencyObject dependencyObject, bool parameter)
{
dependencyObject.SetValue(IsEmptyFocusedProperty, parameter);
}
public static bool GetIsEmptyFocused(DependencyObject dependencyObject)
{
return (bool)dependencyObject.GetValue(IsEmptyFocusedProperty);
}
}
回答4:
If you want this code:
window.onload = function()
{ document.getElementById('Xaml1').focus(); }
work in all browsers, you must set the tabIndex for element with id="Xaml1".
Sorry for my English :)
回答5:
I just did a quick test and it looks like this solve the problem in the browser too!
How to set focus on TextBox in Silverlight 4 out-of-browser popup
来源:https://stackoverflow.com/questions/1126424/setting-initial-control-focus-in-silverlight