简体   繁体   English

如何将焦点重新设置为控制起源回发

[英]How to set focus back to control that originated postback

To avoid unwarranted "duplicate" flagging, let me say upfront - I have searched high and low for an answer and only found ones like this , which has no answer, or this , which tells me to use MyControl.Focus(); 为了避免不必要的“重复”标记,让我在前面先说-我在上下搜索了一个答案,只找到了诸如this ,没有答案或this的答案,这告诉我使用MyControl.Focus(); from my code behind. 从我后面的代码。 That does not work properly. 不能正常工作。 I will explain. 我会解释。

I have a series of dropdown controls in an update panel, each of which affects the ones after it - City, Building and Room. 我在更新面板中有一系列下拉菜单控件,每个下拉菜单控件都会影响之后的控件-城市,建筑物和房间。 When the user changes the selection in the city dropdown, mouse or keyboard, focus is immediately lost as the page does the partial postback. 当用户在城市下拉菜单(鼠标或键盘)中更改选择时,由于页面会进行部分回发,因此焦点会立即丢失。 Ok, so I try to put in the CityListDropDown.Focus(); 好的,所以我尝试放入CityListDropDown.Focus(); , but that causes the page to reposition itself so that this control is at the bottom of the visible area of the page - not the desired behavior. ,但这会导致页面重新定位,因此此控件位于页面可见区域的底部,而不是所需的行为。 The page should not move at all. 页面根本不会移动。 Mind you, this only matters if you have a lot of other stuff on the page before your update panel, so that these prompts are lower down where the page has had to scroll down to them. 请注意,这仅在您在更新面板之前页面上还有很多其他内容的情况下才重要,这样这些提示就会在页面必须向下滚动到它们的位置降低。

So, how do I restore focus back to that city drop down so when the user is using the keyboard, they can just keep on trucking to the next prompt? 因此,如何将焦点恢复到该城市下拉菜单,以便当用户使用键盘时,他们可以继续将卡车运送到下一个提示? Same goes for the building drop down. 建筑物下降也是如此。

Here is my html: 这是我的html:

            <asp:UpdatePanel ID="RoomsUpdatePanel" runat="server" UpdateMode="Conditional" RenderMode="Inline">
                <ContentTemplate>
                                <asp:DropDownList ID="CityListDropDown" runat="server" class="form-control input-sm" Width="140" AutoPostBack="True" OnSelectedIndexChanged="CityListDropDown_SelectedIndexChanged">
                                </asp:DropDownList>
                                <asp:DropDownList ID="BuildingListDropDown" runat="server" class="form-control input-sm" AutoPostBack="True" Width="100" OnSelectedIndexChanged="BuildingListDropDown_SelectedIndexChanged">
                                </asp:DropDownList>
                                <asp:DropDownList ID="RoomListDropDown" runat="server" class="form-control input-sm" AutoPostBack="False" Width="175">
                                </asp:DropDownList>
                </ContentTemplate>
            </asp:UpdatePanel>

and here is my code behind: 这是我的代码背后:

    protected void CityListDropDown_SelectedIndexChanged(object sender, EventArgs e)
    {
        LoadBuildingList();
        LoadRoomList();
        CityListDropDown.Focus();
    }

    protected void BuildingListDropDown_SelectedIndexChanged(object sender, EventArgs e)
    {
        LoadRoomList();
        BuildingListDropDown.Focus();
    }

If you don't want the page to scroll / get repositioned whenever the focus is changed, you can use the PageMaintainScrollPositionOnPostback property of the Page directive : 如果您不希望页面在焦点改变时滚动/重新定位,则可以使用Page指令的PageMaintainScrollPositionOnPostback属性:

<%@ PageMaintainScrollPositionOnPostback="true" ... %>

or you can try setting it programatically through code : 或者您可以尝试通过代码以编程方式设置它:

Page.MaintainScrollPositionOnPostBack = true;

I got it! 我知道了! So using the code behind Focus() method of the control causes the page to reposition itself, even when you have set the MaintainScrollPositionOnPostBack property of the page to true. 因此,即使将页面的MaintenanceScrollPositionOnPostBack属性设置为true,使用控件的Focus()方法后面的代码也会导致页面重新定位。 But, javascript can change focus without moving the page around unnecessarily. 但是,javascript可以更改焦点,而无需不必要地移动页面。 So if I need to reset focus from my code behind, to the sending control, I can do this: 因此,如果需要将焦点从后面的代码重置为发送控件,则可以执行以下操作:

    protected void CityListDropDown_SelectedIndexChanged(object sender, EventArgs e)
    {
        LoadBuildingList();
        LoadRoomList();
        ScriptManager.RegisterStartupScript(CityListDropDown, CityListDropDown.GetType(), "CityDropDownRefocus", "document.getElementById(\"" + CityListDropDown.ClientID + "\").focus();", true);
    }

or, if I want that line of code that resets the focus to be more generic (say I have an event handler that is used by multiple controls, and I need the handler to reset focus to the control that generated the postback, the handler is going to get the sending object, so I can say: 或者,如果我希望将焦点重设的代码行更加通用(例如,我有一个由多个控件使用的事件处理程序,并且我需要该处理程序将焦点重设至生成回发的控件,则该处理程序为要获取发送对象,所以我可以说:

protected void MyControlHandler(object sender, EventArgs e)
{
    ...
    ScriptManager.RegisterStartupScript((WebControl)sender, sender.GetType(), "CityDropDownRefocus", "document.getElementById(\"" + ((WebControl)sender).ClientID + "\").focus();", true);
}

And that resets the focus back to the sending control, without moving the page around! 这样就可以将焦点重新设置为发送控件,而无需四处移动页面!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM