Last Updated: 21 Mar 2021 15:20 by ADMIN
Created on: 10 Mar 2021 09:00
Category: Window
Type: Feature Request
Prevent the user from dragging a window out of the viewport

You can move a modal window past the bottom and out of view. At that point the only way to get back to it is to zoom out on the browser. Similarly, if you drag a window to the top, you can move it so high that the title bar is out of view. You can still see the bottom part of the window but even if you zoom out you can't get back to the title bar so the only thing you can do is to either escape out of the window or hope you have Ok/Cancel still visible.



Until a feature is implemented that can do this automatically (whether behind a flag like in our WebForms suite or not), you can handle the window events to check the Top and Left values and compare them with the viewport and the window size.

Here is a basic example:

<TelerikWindow Left="@TheLeft" Top="@TheTop" Draggable="true"
               LeftChanged="@LeftChangedHandler" TopChanged="@TopChangedHandler"
               Visible="true" Width="400px" Height="300px">
    <WindowTitle>Drag me!</WindowTitle>
    <WindowContent>When using Left and Top, make sure to update them in the view-model.</WindowContent>
        <WindowAction Name="Minimize"></WindowAction>
        <WindowAction Name="Maximize"></WindowAction>

    string TheLeft { get; set; } = "50px";
    string TheTop { get; set; } = "50px";

    async Task LeftChangedHandler(string currLeft)
        float leftValue = float.Parse(currLeft.Replace("px", ""));
        Console.WriteLine("left " + leftValue);
        //left boundary
        if (leftValue < 0)
            currLeft = "0px";
        //right boundary - replace hardcoded values with current values from the viewport size
        //and take into account the dimensions of your window. This sample hardcodes values for brevity and clarity
        //you may find useful packages like this to get the viewport size https://www.nuget.org/packages/BlazorPro.BlazorSize/
        if (leftValue > 1000)
            currLeft = "1000px";

        TheLeft = currLeft;

        await DelayedRender();

    async Task TopChangedHandler(string currTop)
        float topValue = float.Parse(currTop.Replace("px", ""));
        Console.WriteLine("top: " + topValue);

        //top boundary
        if (topValue < 0)
            currTop = "0px";
        //bottom boundary - replace hardcoded values with current values from the viewport size
        //and take into account the dimensions of your window
        if (topValue > 600)
            currTop = "600px";

        TheTop = currTop;

        await DelayedRender();

    async Task DelayedRender()
        await Task.Run(async () =>
            await Task.Delay(30);
            await InvokeAsync(StateHasChanged);


Marin Bratanov
Posted on: 21 Mar 2021 15:20

Hi Doug,

For latencies as high as 200ms, I can suggest you consider the WebAssembly flavor. You can read more about the problems latency introduces here.

I can also suggest you optimize this a little - keep track of the window size as it resizes (hook to window.resize, e.g., through packages like this one) and with that the view model will know the browser size - the user can't simultaneously move the window and resize the browser anyway. With this, you can eliminate the need to query the browser on each event call.

Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Posted on: 20 Mar 2021 01:11
This method mostly works but it does have one issue. In your handler methods if you have to call out to JavaScript or whatever else that takes a little time, and you move the window twice in quick succession the window will bounce back to its original location and then bounce to where it's supposed to be. Running locally through debug it's not that much of an issue but in a deployed scenario where everything is going across the pipe it's more exaggerated. To recreate it you can add "await Task.Delay(200);" to your handler methods before setting the top and left values. You can increase the number of milliseconds to make the issue easier to recreate locally. This isn't a major issue but I think some of my users may have a pretty slow connection so it might become more exaggerated when we go live.