Kohnarik
Kohnarik

Reputation: 377

C# Repeater focusing the first element after DataSource is changed

I have a Repeater with a certain DataSource (consisting of a list of images). The Repeater holds ImageButtons.

The aspx:

<asp:Panel ID="panSearch" runat="server" ScrollBars="Vertical" BorderColor="#333333" BorderStyle="Inset" Width="500" Height="200">
    <asp:Repeater ID="Repeater" runat="server">
        <ItemTemplate> 
            <asp:ImageButton OnClick="imgSearchResult_Click" BackColor="#333333" ID="imgSearchResult" height="32" width="32" runat="server" ImageUrl='<%# Eval("ImageUrl") %>'/> 
        </ItemTemplate>
    </asp:Repeater>
</asp:Panel> 

Additionally, I have a TextBox, which has a TextChanged-event in code-behind. I do a few things in there and at the end, my Repeater's DataSource will be overwritten with a new List of images (those images are put into the ImageButtons).

Repeater.DataSource = ImageList;
Repeater.DataBind();

My problem: Whenever my Repeater.DataSource is changed, it "clicks" the first ImageButton inside the Repeater. How do I prevent that from happening?


Full code:

My TextBox:

<asp:TextBox ID="textSearch" runat="server" Width="80" OnTextChanged="textSearch_TextChanged" ForeColor="Black" />

My TextChanged event:

protected void textSearch_TextChanged(object sender, EventArgs e)
{
    string[] filesindirectory = Directory.GetFiles(Server.MapPath("~/Images/ORAS"));
    List<System.Web.UI.WebControls.Image> ImageList = new List<System.Web.UI.WebControls.Image>(filesindirectory.Count());

    foreach (string item in filesindirectory)
    {
        System.Web.UI.WebControls.Image myImage= new System.Web.UI.WebControls.Image();
        myImage.ImageUrl = (String.Format("~/Images/ORAS/{0}", System.IO.Path.GetFileName(item)));
        ImageList.Add(myImage);
    }
    Repeater.DataSource = ImageList;
    Repeater.DataBind();
}

When I click on an ImageButton inside the Repeater (which is executed when the text in my TextBox is changed):

protected void imgSearchResult_Click(object sender, ImageClickEventArgs e)
{
    var selectedImage = sender as ImageButton;
    if (img1.ImageUrl == "~/Images/ORAS/Empty/000.png")
    {
        img1.ImageUrl = selectedImage.ImageUrl;
    }
    else if (img2.ImageUrl == "~/Images/ORAS/Empty/000.png")
    {
        img2.ImageUrl = selectedImage.ImageUrl;
    }
    else if (img3.ImageUrl == "~/Images/ORAS/Empty/000.png")
    {
        img3.ImageUrl = selectedImage.ImageUrl;
    }
    else if (img4.ImageUrl == "~/Images/ORAS/Empty/000.png")
    {
        img4.ImageUrl = selectedImage.ImageUrl;
    }
    else if (img5.ImageUrl == "~/Images/ORAS/Empty/000.png")
    {
        img5.ImageUrl = selectedImage.ImageUrl;
    }
    else if (img6.ImageUrl == "~/Images/ORAS/Empty/000.png")
    {
        img6.ImageUrl = selectedImage.ImageUrl;
    }
    else
    {
        ErrorMessage("Please remove one Image first!", true);
    }
}

Pageload:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        img1.ImageUrl = "~/Images/ORAS/Empty/000.png";
        img2.ImageUrl = "~/Images/ORAS/Empty/000.png";
        img3.ImageUrl = "~/Images/ORAS/Empty/000.png";
        img4.ImageUrl = "~/Images/ORAS/Empty/000.png";
        img5.ImageUrl = "~/Images/ORAS/Empty/000.png";
        img6.ImageUrl = "~/Images/ORAS/Empty/000.png";
        LoadImages();
    }
}

(LoadImages is almost 1:1 what's in my TextChanged function)

Upvotes: 0

Views: 406

Answers (1)

Balah
Balah

Reputation: 2540

I really am not sure how (why) ASP.NET WebForms does it, but if you hit Enter and the form posts back, it will find the first control that implements IPostBackEventHandler and execute whatever event is bound to that. ImageButton implements it and so that's why it keeps firing the click event even though you didn't click on it. And, once again, only if you hit Enter.

I think that behaviour happens because the data posted back - __EVENTTARGET and __EVENTARGUMENT - are empty. Then ASP.NET goes bonkers.

You can solve it by putting a dummy button at the top of the page (or masterpage) and hide it using the style attribute. so:

<asp:Button ID="dummy" runat="server" style="display:none" />

Then in the init or load of your page (or masterpage) put

Form.DefaultButton = dummy.UniqueID;

That will force the button to capture the enter press instead of the arbitrary image button.

Upvotes: 1

Related Questions