This is a migrated thread and some comments may be shown as answers.

Docks are duplicating on save

1 Answer 37 Views
Dock
This is a migrated thread and some comments may be shown as answers.
Logan
Top achievements
Rank 1
Logan asked on 11 Aug 2010, 04:10 PM
Hello, I have a Rad Dock and I am saving the layout into a database, I am saving whenever I move a dock item. The problem is if I move a dock item around too much, or move an item erratically the item duplicates. I attached the html and vb.net can anyone help me with this problem?

VB.net
Imports System.Web.Script.Serialization

Partial Class MyLanding
    Inherits System.Web.UI.Page
    Private LoginClass As New LoginClass
    Private _dockStateCleared As Boolean = False
    Private _conn As New SqlConnection(ConfigurationManager.ConnectionStrings("MidwestPartsConnectionString").ConnectionString)

    Private ReadOnly Property CurrentDockStates() As List(Of DockState)
        Get
            'Get saved state string from the database - set it to dockState variable for example
            Dim dockStatesFromDB As String = ""

            _conn.Open()
            Dim command As New SqlCommand("SELECT JavascriptStr FROM SysProperties WHERE (UserID = @UserID)", _conn)
            command.Parameters.Add("@UserID", SqlDbType.UniqueIdentifier).Value = Me.LoginClass.ReturnUserID()
            Try
                dockStatesFromDB = command.ExecuteScalar().ToString()
                _conn.Close()
            Catch ex As Exception
                _conn.Close()
                Me.CreateSavedLayout("")
            End Try

            Dim _currentDockStates As New List(Of DockState)()
            Dim stringStates As String() = dockStatesFromDB.Split("|"c)
            For Each stringState As String In stringStates
                If stringState.Trim() <> String.Empty Then
                    _currentDockStates.Add(DockState.Deserialize(stringState))
                End If
            Next
            Return _currentDockStates
        End Get
    End Property


    Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
        If Not Page.IsPostBack Then
            If CurrentDockStates.Count = 0 Then
                Me.LoadItems()
            End If
        End If
    End Sub

    Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Init
        Dim i As Integer = 0
        While i < CurrentDockStates.Count
            If CurrentDockStates(i).Closed = False Then
                Dim dock As RadDock = CreateRadDockFromState(CurrentDockStates(i))
                dlColumnOne.Controls.Add(dock)
                CreateSaveStateTrigger(dock)
                LoadUserControl(dock)
            End If
            System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
        End While
    End Sub

    Protected Sub dlColumnOne_LoadDockLayout(ByVal sender As Object, ByVal e As DockLayoutEventArgs)
        For Each state As DockState In CurrentDockStates
            e.Positions(state.UniqueName) = state.DockZoneID
            e.Indices(state.UniqueName) = state.Index
        Next
    End Sub
    Protected Sub dlColumnOne_SaveDockLayout(ByVal sender As Object, ByVal e As DockLayoutEventArgs)
        Dim stateList As List(Of DockState) = dlColumnOne.GetRegisteredDocksState()
        Dim serializedList As New StringBuilder()
        Dim i As Integer = 0

        While i < stateList.Count
            serializedList.Append(stateList(i).ToString())
            serializedList.Append("|")
            System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
        End While

        Dim dockState As String = serializedList.ToString()
        If dockState.Trim() <> [String].Empty Then
            _conn.Open()
            Dim command As New SqlCommand([String].Format("update sysproperties set javascriptstr = '{0}' Where UserID = @UserID ", dockState), _conn)
            command.Parameters.Add("@UserID", SqlDbType.UniqueIdentifier).Value = Me.LoginClass.ReturnUserID()
            command.ExecuteNonQuery()
            _conn.Close()
        End If
    End Sub

    Private Function CreateRadDockFromState(ByVal state As DockState) As RadDock
        Dim dock As New RadDock()
        dock.DockMode = DockMode.Docked
        dock.UniqueName = state.UniqueName
        dock.ID = String.Format("RadDock{0}", dock.UniqueName)
        dock.ApplyState(state)
        dock.Commands.Add(New DockCloseCommand())
        dock.Commands.Add(New DockExpandCollapseCommand())
        Return dock
    End Function

    Private Function CreateRadDock(ByVal DockTitle As String) As RadDock
        Dim docksCount As Integer = CurrentDockStates.Count
        Dim dock As New RadDock
        dock.DockMode = DockMode.Docked
        Dim UniqueName As String = Guid.NewGuid().ToString()
        UniqueName = UniqueName.Replace("-", "")
        dock.UniqueName = UniqueName
        dock.ID = String.Format("RadDock{0}", UniqueName)
        dock.Title = DockTitle
        dock.Width = Unit.Pixel(400)
        dock.Commands.Add(New DockCloseCommand())
        dock.Commands.Add(New DockExpandCollapseCommand())
        Return dock
    End Function

    Private Sub LoadItems()
        Dim DocksDataTable As DataTable = Me.ReturnReports()
        For i = 0 To DocksDataTable.Rows.Count() - 1
            Dim dock As RadDock = Me.CreateRadDock(DocksDataTable.Rows(i).Item("ReportTitle").ToString())
            Dim dz As RadDockZone = Me.dzColumnOne
            Dim dl As RadDockLayout = Me.dlColumnOne
            dz.Controls.Add(dock)
            Me.CreateSaveStateTrigger(dock)
            dock.Tag = DocksDataTable.Rows(i).Item("ReportPath")
            Me.LoadUserControl(dock)
        Next
    End Sub

    Public Function ReturnReports() As DataTable
        Dim connection As New SqlConnection(ConfigurationManager.ConnectionStrings("MidwestPartsConnectionString").ConnectionString)
        Dim Query As String = "SELECT Reports.ReportPath, Reports.ReportTitle, UserReports.UserID FROM UserReports INNER JOIN Reports ON UserReports.ReportID = Reports.ReportID WHERE (UserReports.UserID = @UserID)"
        Dim adapter As New SqlDataAdapter
        adapter.SelectCommand = New SqlCommand(Query, connection)
        adapter.SelectCommand.Parameters.Add("@UserID", SqlDbType.UniqueIdentifier).Value = Me.LoginClass.ReturnUserID()
        Dim table1 As New DataTable
        connection.Open()
        Try
            adapter.Fill(table1)
        Finally
            connection.Close()
        End Try
        Return table1
    End Function

    Private Function ReturnLayout() As DataTable
        Dim connection As New SqlConnection(ConfigurationManager.ConnectionStrings("MidwestPartsConnectionString").ConnectionString)
        Dim Query As String = "select * from sysproperties"
        Dim adapter As New SqlDataAdapter
        adapter.SelectCommand = New SqlCommand(Query, connection)
        adapter.SelectCommand.Parameters.Add("@UserPropertiesID", SqlDbType.Int).Value = 1
        Dim table1 As New DataTable
        connection.Open()
        Try
            adapter.Fill(table1)
        Finally
            connection.Close()
        End Try
        Return table1
    End Function

    Private Sub LoadUserControl(ByVal dock As RadDock)
        If String.IsNullOrEmpty(dock.Tag) Then
            Return
        End If
        Dim usercontrol As Control = LoadControl(dock.Tag)
        dock.ContentContainer.Controls.Add(usercontrol)
    End Sub

    Private Sub CreateSaveStateTrigger(ByVal dock As RadDock)
        dock.AutoPostBack = True
        dock.CommandsAutoPostBack = True
        Dim saveStateTrigger As New AsyncPostBackTrigger()
        saveStateTrigger.ControlID = dock.ID
        saveStateTrigger.EventName = "DockPositionChanged"
        UpdatePanel1.Triggers.Add(saveStateTrigger)
        saveStateTrigger = New AsyncPostBackTrigger()
        saveStateTrigger.ControlID = dock.ID
        saveStateTrigger.EventName = "Command"
        UpdatePanel1.Triggers.Add(saveStateTrigger)
    End Sub

    Private Sub CreateSavedLayout(ByVal JavascriptStr As String)
        Dim sqlConn As New SqlConnection(ConfigurationManager.ConnectionStrings("MidwestPartsConnectionString").ConnectionString)        
        Dim strSqlInsert As String = "INSERT INTO SysProperties(UserID, JavascriptStr) VALUES (@UserID, @JavascriptStr)"
        strSqlInsert += "; SELECT SCOPE_IDENTITY() ;"
        Dim sqlCmd As New SqlCommand(strSqlInsert, sqlConn)
        With sqlCmd.Parameters
            .Add("@JavascriptStr", SqlDbType.Text).Value = JavascriptStr
            .Add("@UserID", SqlDbType.UniqueIdentifier).Value = Me.LoginClass.ReturnUserID()
        End With
        sqlCmd.Connection.Open()
        sqlCmd.ExecuteScalar()
        sqlCmd.Connection.Close()
    End Sub


    Protected Sub btnAddReports_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddReports.Click
        Try
            Response.Redirect("~/MyUserAccount/SelectedReports.aspx", False)
        Catch ex As Exception

        End Try
    End Sub
End Class


1 Answer, 1 is accepted

Sort by
0
Pero
Telerik team
answered on 17 Aug 2010, 09:34 AM
Hello Logan,

The reason for this problem is a conflict between two (or more) ajax requests initiated at the same time. This happens when you quickly move the dock around.
To avoid this from happening you can use one of the following approaches:
  • If you use two UpdatePanels, one invisible and the other that wraps the layout, make sure they are configured in the following way:
    <asp:UpdatePanel runat="server" ID="UpdatePanel2" ChildrenAsTriggers="false" UpdateMode="Conditional">
            <ContentTemplate>
                <br />
                <telerik:RadDockLayout runat="server" ID="RadDockLayout1" OnSaveDockLayout="RadDockLayout1_SaveDockLayout"
                    OnLoadDockLayout="RadDockLayout1_LoadDockLayout">
                           ................................
                </telerik:RadDockLayout>
            </ContentTemplate>
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="ButtonAddDock" EventName="Click" />
            </Triggers>
        </asp:UpdatePanel>
        <div style="width: 0px; height: 0px; overflow: hidden; position: absolute; left: -10000px;">
            Hidden UpdatePanel, which is used to help with saving state when minimizing, moving
            and closing docks. This way the docks state is saved faster (no need to update the
            docking zones).
            <asp:UpdatePanel runat="server" ID="UpdatePanel1">
            </asp:UpdatePanel>
        </div>
    This is how MyPortal example is configured: http://demos.telerik.com/aspnet-ajax/dock/examples/myportal/defaultcs.aspx. You can test the online demo to see if you get the same error.
  • Show AjaxLoadingPanel while an ajax request is in process. This will disable the users to initiate another request, while the other is still in process. In the following project from our Code Library it is explained how this can be done: http://www.telerik.com/community/code-library/aspnet-ajax/docking/save-dockstate-in-database-using-radajaxmanager.aspx

Regards,
Pero
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
Dock
Asked by
Logan
Top achievements
Rank 1
Answers by
Pero
Telerik team
Share this question
or