CodeProject, DotNet

Suspend or resume windows controls to be redraw

Recently, I was facing issue with third party Image Viewer to apply multiple operations before redrawing of images.
Third-party control was not allowing to suspend and resume painting of images inherently. After searching for various solutions, I found a solution that can be achieved using windows message WM_SETREDRAW from an application to Windows to allow changes in that control to be redrawn or to prevent changes in that control from being redrawn.

public class UIDrawController
{
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);

private const int WM_SETREDRAW = 11;

public static void SuspendDrawing(Control ctrl)
{
SendMessage(ctrl.Handle, WM_SETREDRAW, false, 0);
}

public static void ResumeDrawing(Control ctrl)
{
SendMessage(ctrl.Handle, WM_SETREDRAW, true, 0);
ctrl.Refresh();
}
}

Example Usage:


public ImageViewer : UserControl
{

public void LoadDocument(string filename)
{

UIDrawController.SuspendDrawing(this);

OpenImage(filename);
FitToWidth();
Rotate90();
ApplyImageFilters();

UIDrawController.ResumeDrawing(this);
}
}

CodeProject, Database, sql server

Change Tracking example -Sql Server

If there is a requirement to get incremental or changed data from database frequently without putting a heavy load on database objects, then Change Tracking mechanism of Sql Server can be out of the box solution for this requirement. Normally, developers have to do custom implementation to achieve change tracking behavior. It can be implementation by considering triggers, timestamp columns, or maintaining new tables.

Following is step by step instructions to enable and use of change tracking feature in SQL Server.

Step 1: Check if database compatibility level is set to 90 or greater. If It is lower than 90 then change tracking will not work.

SELECT compatibility_level
FROM sys.databases WHERE name = '';

Step 2: Enable Isolation level on a database to Snapshot. It will ensure change tracking information is consistent.

ALTER DATABASE SET ALLOW_SNAPSHOT_ISOLATION ON

Step 3: Set Change tracking on a database.

ALTER DATABASE SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 2 DAYS,AUTO_CLEANUP = ON)

CHANGE_RETENTION: It specifies the time period for which change tracking information is kept
AUTO_CLEANUP: It enables or disables the cleanup task that removes old change tracking information.

Step 4: Enable change tracking on a table.

ALTER TABLE
ENABLE CHANGE_TRACKING
WITH (TRACK_COLUMNS_UPDATED = OFF)

TRACK_COLUMNS_UPDATED: Setting value to “ON” will make SQL Server Engine storing extra information about columns which are enabled for change tracking. ‘OFF’ is default value to avoid extra overhead on SQL Server to maintain extra columns information.

Step 5: Example to get changed data.

It is example of SQL procedure which will only send changed data from table. Application can pass @lastVersion = 0 first time and going forward application can keep the last version in the cache and pass on last stored version.


CREATE PROCEDURE [dbo].[GetIncrementalChanges]
@lastVersion BIGINT = 0 OUTPUT
AS
BEGIN
DECLARE @curVersion BIGINT = CHANGE_TRACKING_CURRENT_VERSION()
IF @lastVersion = 0
BEGIN
SELECT
a.*
FROM a
END
ELSE
BEGIN
SELECT
a.*
FROM a
INNER JOIN CHANGETABLE(CHANGES , @lastVersion) ct ON A.Id= ct.Id
END

SET @lastVersion = @curVersion

END

Disable Change Tracking

1. Before disabling change tracking on a database, all tables should have change tracking disabled.

Testing Sql statements

You can find working example in attached SQL file or code below:

changetracking


SET NOCOUNT ON
go
PRINT 'Creating test database'
Go
CREATE DATABASE testDb
GO
USE testDb
go
PRINT 'Get compatibility level of db'
GO

SELECT compatibility_level
FROM sys.databases WHERE name = 'v';

GO
PRINT 'Setting db isolation level'
ALTER DATABASE testDb SET ALLOW_SNAPSHOT_ISOLATION ON;

GO
PRINT 'Creating table testchange'
GO
CREATE TABLE dbo.TestChange
(
Id INT NOT NULL ,
NAME VARCHAR(20)
NOT NULL CONSTRAINT [PK_ID] PRIMARY KEY CLUSTERED ( [Id] ASC )
);

GO
PRINT 'Inserting initial values'
GO

INSERT INTO dbo.TestChange
( Id, NAME )
VALUES ( 1, -- Id - int
'ABC' -- NAME - varchar(2)
),
( 2, 'XXX' );
GO

PRINT 'See current change tracking version before Change tracking enabled';

SELECT [change tracking version after Enabling] = CHANGE_TRACKING_CURRENT_VERSION();
GO
PRINT 'Enable Change Tracking on database';

ALTER DATABASE testDb SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 2 DAYS,AUTO_CLEANUP = ON)

GO
PRINT 'Enable Change Tracking on testchange table';
GO
ALTER TABLE dbo.TestChange
ENABLE CHANGE_TRACKING
WITH (TRACK_COLUMNS_UPDATED = OFF);

GO

SELECT [change tracking version after Enabling] = CHANGE_TRACKING_CURRENT_VERSION();

GO
CREATE PROCEDURE [dbo].[GetIncrementalChanges]
@lastVersion BIGINT = 0 OUTPUT
AS
BEGIN
DECLARE @curVersion BIGINT = CHANGE_TRACKING_CURRENT_VERSION()
IF @lastVersion = 0
BEGIN
SELECT
a.*
FROM TestChange a
END
ELSE
BEGIN
SELECT
a.*
FROM TestChange a
INNER JOIN CHANGETABLE(CHANGES dbo.TestChange, @lastVersion) ct ON A.Id= ct.Id
END

SET @lastVersion = @curVersion

END
GO

DECLARE @lastVersion1 BIGINT =0

EXECUTE dbo.GetIncrementalChanges @lastVersion = @lastVersion1 OUTPUT -- bigint

PRINT 'Get Last Version'
SELECT [Last Version] = @lastVersion1

PRINT 'insert new rows in table'

INSERT INTO dbo.TestChange
( Id, NAME )
VALUES ( 3, -- Id - int
'YYYY' -- NAME - varchar(2)
),
( 4, -- Id - int
'ZZZ' -- NAME - varchar(2)
)

EXECUTE dbo.GetIncrementalChanges @lastVersion = @lastVersion1 OUTPUT -- bigint

PRINT 'Get latest Version'
SELECT @lastVersion1

INSERT INTO dbo.TestChange
( Id, NAME )
VALUES ( 5, -- Id - int
'KKKK' -- NAME - varchar(2)
),
( 6, -- Id - int
'LLLL' -- NAME - varchar(2)
)

EXECUTE dbo.GetIncrementalChanges @lastVersion = @lastVersion1 OUTPUT -- bigint

PRINT 'Get latest Version'
SELECT @lastVersion1

GO
PRINT 'Disable Change Tracking on table'
ALTER TABLE dbo.TestChange
DISABLE CHANGE_TRACKING
GO
PRINT 'Current change tracking version after disabling';
SELECT [change tracking version after disabling] = CHANGE_TRACKING_CURRENT_VERSION()
GO
PRINT 'Disable Change Tracking on Database'

ALTER DATABASE testDb SET CHANGE_TRACKING = OFF

GO

PRINT 'test complete, dropping database'
USE master
Go
DROP DATABASE testDb

Architecture, DotNet, Software Engineering

Importance of Use Case Document

“JSON, XML, .Net, C++, Java, Middleware”. These are some of the technical jargon which many IT professionals use while having a discussion with business users to implement business requirements. Business users might not be interested into how the system will be developed technically. Mostly, they are interested in if the proposed or existing systems are aligned with business requirements or expectations.

Use cases fill that gap and help stakeholders to understand “what software does”. Use cases offer the business analysts, development, and testing teams an invaluable guidebook. It does not include too many technical details and it is not as abstract as the business requirement. 

A typical use case should capture how a user will interact with the system to achieve a specific goal, it should highlight alternate and exceptions flow if normal flows are preventing users to execute further steps.

Benefits of having use cases in Software Development Life Cycle:

Use cases can help business stakeholders:

  • To understand proposed or existing software better without going into technical details.
  • They can evaluate use cases against business requirements; it will be easy to provide sign-off to IT team.
  • Highlight assumptions, out-of-scope items, outstanding issues for specific use case flow.

Use cases can help development and testing team:

  • To understand business processes and flows.
  • To understand functional context, Exceptions, Alternate flows.
  • To understand Pre-Conditions, Post-Conditions & Triggers for use case flow.
  • Work as a foundation for making test cases and testing delivered software against business requirements.

Use Case Document

Use cases can be depicted in a document with the visual and textual representation of workflows. It can be structured into following elements:

  • Introduction – Brief description of use case scope.
  • Actors – A list of the types of users who can engage in the activities described in the use case. Actor names should not correspond to job titles.
  • Participants – A list of software applications or systems which will be used in use case flow.
  • Description – description of use case.
  • Triggers – anything which will invoke use case to begin.
  • Data Flow / Activity Diagram/ Use Case: Represent user
  • Preconditions – Anything the solution can assume to be true when the use case begins.
  • Normal/Basic Flow – The set of steps the actors take to accomplish the goal of the use case. A clear description of what the system does in response to each user action.
  • Alternate Flows – Capture the less common user/system interactions, such as being on a new computer and answering a security question.
  • Exception Flows – The things that can happen that prevent the user from achieving their goals, such as providing an incorrect username and password.
  • Post-Conditions – Anything that must be successfully done when the use case is complete.
  • Assumptions Write assumptions if any.
  • Notes and Issues List down any issues or points to highlight.

I have uploaded sample use case document for reference.

use-case-sample

    

Asp.Net, C#, Java Script, Jquery, Web

Convert base64 string into file using Java script

Here you find java script code convert base64 string to file. I converted excel file to base64 string to demo example. I did it in c# code.

Code to convert file into Base64

using System;
using System.IO;
using System.Linq;

namespace Demo
{
public class Program
{
public static void Main(string[] args)
{
var fileBytes = File.ReadAllBytes(@”d:\temp.xlsx”);

string encodedFile = Convert.ToBase64String(fileBytes);

Console.WriteLine(“Base 64 Encoded File : {0}”, encodedFile);

var decodedFileBytes = Convert.FromBase64String(encodedFile);

File.AppendAllText(“d:\\temp.txt”,encodedFile);

File.WriteAllBytes(@”d:\newtempfile.xlsx”, decodedFileBytes);
}
}
}

You can expose file upload or download via service where file can be transferred as base64 string.
Java script code to consume base64 string and download as file:

 

function convertBase64ToExcel()
{

var data = “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”;

var contentType = ‘application/vnd.ms-excel’;
var blob1 = b64toBlob(data, contentType);
var blobUrl1 = URL.createObjectURL(blob1);

window.open(blobUrl1);

}

function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || ”;
sliceSize = sliceSize || 512;

var byteCharacters = atob(b64Data);
var byteArrays = [];

for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);

var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}

var byteArray = new Uint8Array(byteNumbers);

byteArrays.push(byteArray);
}

var blob = new Blob(byteArrays, {type: contentType});
return blob;
}

You can find running code here: Jsfiddle

//jsfiddle.net/neerajkaushik_123/s9g9nqa1/6/embedded/