Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Thursday, February 20, 2014

FocusMonitor Identifies Processes Stealing Focus

Recently I've been having issues with some process stealing focus from the application I'm working in.

Like I'll be in Visual Studio or Word or Waterfox (a 64-bit performance focused build of Firefox) and suddenly focus is swapped for a split second and whatever word I'm typing gets cut off or a button I'm clicking isn't.

I found a very helpful post by Matt Gertz from some years back where he provides some VB.NET code for an application that can monitor processes that steal focus from it. I'm more of a C# guy myself, so I've run with Matt's core logic and created a 32-bit C# application in Visual Studio 2010 which provides similar functionality. It will also let you copy the log info to the clipboard to paste wherever for further examination.




I call it FocusMonitor, and you can download the source code.





Friday, December 27, 2013

LinkButton OnClick Not Firing After OnClientClick

I worked around an oddball problem where the OnClick event of an ASP LinkButton would not fire following execution of some JavaScript tied to its OnClientClick.

The intent is to enable a row in a Telerik RadGrid to be removed by clicking the corresponding button in the row, and more specifically have a modal confirmation dialog appear to prompt the user to confirm their choice.

Here's markup for the GridTemplateColumn containing the button:
<telerik:GridTemplateColumn HeaderText="Remove" UniqueName="Remove" 
  FilterControlWidth="20">
    <ItemTemplate>
        <div style="cursor: hand;">
            <asp:LinkButton runat="server" ID="_RemoveItem" 
                Name="_RemoveItem" Text=" X " Font-Underline="False" 
                ForeColor="DarkBlue" 
                OnClientClick="confirmAspButton(this, 'Are you sure?'); return false;"
                OnClick="RemoveItemButtonClick" 
                style="font-weight:bold;color:red;">
            </asp:LinkButton>
        </div>
    </ItemTemplate>
    <HeaderStyle Width="55"></HeaderStyle>
</telerik:GridTemplateColumn>

The confirmAspButton function is a little JavaScript which is bound to the OnClientClick method of the LinkButton. If the user clicks OK, the confirmation passes and a postback will occur to execute the code beneath the OnClick method, whereas if they click Cancel the dialog will simply disappear.
     function confirmAspButton(button, message) 
     {
          function aspButtonCallbackFn(arg) 
          {
             if (arg) 
             {
                  window.__doPostBack(button.name, "");
             }
          }
            
          window.radconfirm(message, aspButtonCallbackFn, 330, 120, null, "Confirm");
     }


Seems simple enough, yet for some odd reason, in Internet Explorer 10, the LinkButton brought up the dialog just fine, and although the Cancel button click performed as expected, clicking OK had the same effect as cancel and merely cleared the dialog without executing the underlying code.

I managed to find a workaround via StackOverflow which suggests using a Button rather than a LinkButton. Sure enough, this did the trick, for whatever oddball reason whose particulars I could care less to dive into...




Tuesday, May 7, 2013

The "GenerateResource" Task Failed Unexpectedly

Shortly after setting up a RAM disk using the freeware version of Dataram RAMDisk to see whether Visual Studio 2010 might compile a huge solution faster, I began getting the following errors after relocating the system's temp files to the root of the RAM drive:
The "GenerateResource" task failed unexpectedly.
System.TypeInitializationException: The type initializer for 'Microsoft.Build.Utilities.FileTracker' threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object.

I dug around and found numerous references to existing bug reports and a few workarounds. I tried unsetting the readonly file system attribute in my solution folder, setting the GenerateResourceNeverLockTypeAssemblies property in my project file to true or false to downgrade some security parameters, but ultimately it was the top answer here that did the trick.

I had set the environment variables for the RAM drive initially to just R:\, referencing the root of the drive. Apparently VS 2010 doesn't like this, so I simply created a new folder on my ram disk named TEMP, and then updated the environment variables accordingly:




Just to rule it out, and also because I hadn't rebooted Windows in a while, I also opened Control Panel => Programs and Features, and performed a Repair on Microsoft .NET Framework 4 Client Profile just in case the framework files might've gotten corrupted somehow, and then restarted.

Problem solved! Now on to see whether Joseph Fluckiger's experimentation which returned lukewarm results on performance of building to a RAM disk holds water for a solution with, say, dozens of projects.



Friday, June 1, 2012

Obtain Element Coordinates Using JQuery

I'm working on a project with ASP.NET and JQuery where I need to be able to obtain the coordinates for a div element in response to a button click. I found an example here, but I wanted to get not just the top and left values, but be able to obtain coordinates of all four corners.

To do this, I make use of JQuery's position, height, and width functions, then simply use some arithmetic to obtain the coordinates and finally display them. 

Here's an example. First, the markup:
<%@ Page Title="Home Page" Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

Div Coordinates





I am a div.

Now, the code behind: 

protected void Button1_Click(object sender, EventArgs e)
{
     Label1.Text = "Top Left: " + hfTop.Value + ", " + hfLeft.Value;
     Label2.Text = "Top Right: " + hfTop.Value + ", " + hfRight.Value;
     Label3.Text = "Bottom Left: " + hfBottom.Value + ", " + hfLeft.Value;
     Label4.Text = "Bottom Right: " + hfBottom.Value + ", " + hfRight.Value;
}



In a nutshell, the button click first triggers the OnClientClick event, which calls the JQuery functions to populate the values of the HiddenField objects. Then, the OnClick method takes those values and concatenates them in the code behind into coordinate pairs to display as the label text.
In cases where we need specific coordinates of each corner of a div element in response to a click event, this method works nicely.



Wednesday, September 14, 2011

Assembly must be Strong Signed in order to be marked as a Prerequisite

In the process of trying to update and rebuild a C# project utilizing Microsoft's Enterprise Library, I inexplicably got the error "Microsoft.Practices.EnterpriseLibrary.Data.dll must be strong signed in order to be marked as a prerequisite." 

I hadn't touched this project in a while, in fact I may've last built it on a different PC, so I guess if I had strong signed the Enterprise Library dll, the new system had no idea. Also, I'd installed .NET 4 recently, so maybe this had something to do with this earlier version of the Enterprise LIbrary (my project implements 4.1 whereas the latest version is 5). I guess security in the .NET 3.5 framework isn't up to snuff as far as .NET 4 is concerned.

Anyway, it appeared I had no choice but to use the sn.exe utility and create a key pair and do all the stuff Microsoft suggests in their painfully tedious article on how to sign an assembly with a strong name. Luckily after some digging I found Signer, a command-line utility which simplifies the process of strongly signing one or more assemblies which VS 2008 may be complaining about.

I'm referencing this from the perspective of a Windows 7 64-bit system, so note that the following may vary if you're using 32-bit. 

In order to do it's thing, Signer requires access to some other command line utilities, most of which live in C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\. A few, however, including ilasm.exe and fusion.dll, live elsewhere (in my case, these were hanging out in C:\Windows\Microsoft.NET\Framework64\v4.0.30319).

I decided to copy Signer.EXE to the above SDK path, and copy the latest versions of the above files to that same path, so that when I execute Signer.EXE, it'll be able to easily find all the external EXE and DLL files in the same directory.

First of all, though, I needed to use MIcrosoft's sn utility to create an .snk key file in my SDK folder from a command prompt as follows:
sn.exe -k 1024 myProjectKeyName.snk

This instructs sn to produce a key file named myProjectKeyName.snk which I really don't care about for anything other than getting my project to build again. Thus, I chose an arbitrary key file name and value of 1024-bit key length.

I then executed Signer as follows in the same folder:
signer.exe -k myProjectKeyName.snk -outdir C:\myProject\myProjectLibrary -a C:\myProject\myProjectLibrary\*.dll

Here I'm instructing Signer to take the key I just created and strongly sign all .DLL files in my project's library folder. After this, I did a Clean Build on my project, then a Build, and thank goodness, the build completed successfully!
 
Even though Visual Studio 2008 can't build .NET 4 applications, I guess nevertheless since I have the .NET 4 framework installed, it's mandated that all assemblies shall be strong signed, or the project using them shall not build. Whatever, I'm just happy to have gotten past this issue.


Monday, September 12, 2011

Google-like Filtering with RadGrid and Separate Data Class


I needed to create a Google Suggest style search interface for an ASP.NET page.

Our site recently obtained licenses to the Telerik control suite, and the powerful RadGrid control looked like it was just what I needed. I found this example on the Telerik site.

Key to this setup is having a textbox for the user to input filter criteria, which is then from the user's perspective transformed into a RadComboBox object to house matching results; then once the user selects an item from the dropdown, the RadGrid is bound and displays any matching results.

I encountered a problem because our site uses a centralized class library for CRUD outside of this particular page’s code class, meaning I could not access my application’s data context from within the GridBoundColumn class definition. The Telerik example (specifically in the MyCustomFilteringColumnCS.cs file) performs its own queries as needed using a SqlDataAdapter with a ConnectionString obtained from the application configuration. A simple SELECT statement is executed which returns matching results.

When I tried to reference my centralized data class from within the GridBoundColumn class definition, I got the following error:

Cannot access non-static property … in static context.


Below is the problem code, revealing that the property CurrentUser is inaccessible to the class.

       protected void list_ItemsRequested(object o, RadComboBoxItemsRequestedEventArgs e)
     {
        // Cannot access non-static property 'CurrentUser' in static context.
        using (MyCRUD mc = new MyCRUD(CurrentUser) )
     
  {
              ((RadComboBox)o).DataTextField = DataField;
              ((RadComboBox)o).DataValueField = DataField;
              ((RadComboBox)o).DataSource = mc.GetMatchingAddresses(e.Text);
              ((RadComboBox)o).DataBind();
        }
     }


My GridBoundColumn class does not exist until my application instantiates it with its parent RadGrid object, so I cannot directly assign a property to it. However, I stumbled upon this post which made me realize I could, in the GridBoundColumn class definition, make several changes.

  1. Define a constructor for the class which takes an existing instance of the MyCRUD class as input.
  1. Create a public property in the class definition which can be assigned the MyCRUD object.
  1. Create a private field in the class definition to contain the instance of the MyCRUD object to be utilized by the GridBoundColumn class.
 
Below is the modified class, with additions (*) indicated below.

       public class rgcFilterColumn : GridBoundColumn
      {   
            // * I added a constructor with an input parameter of the type 
            // * corresponding to my app’s CRUD object.       
            public rgcFilterColumn(MyCRUD mycrud)
            {
                TheDataContext = mycrud;
            }

            // * This field provides an instance of the rgcFilterColumn class 
            // * with the corresponding value set for the data context object.
            private readonly MyCRUD TheDataContext;

            // * This property enables the process which instantiates this 
            // * class to assign the MyCRUD object to TheDataContext.
            public MyCRUD thedatacontext
            {
                get { return TheDataContext; }
            }


     // RadGrid will call this method when it initializes
     // the controls inside the filtering item cells
            protected override void SetupFilterControls(TableCell cell)
            {
                base.SetupFilterControls(cell);
                cell.Controls.RemoveAt(0);
                RadComboBox combo = new RadComboBox
                {
                    ID = ("RadComboBox1" + UniqueName),
                    ShowToggleImage = false,
                    Skin = "Office2007",
                    EnableLoadOnDemand = true,
                    AutoPostBack = true,
                    MarkFirstMatch = true,
                    Height = Unit.Pixel(100)
                };
                combo.ItemsRequested += list_ItemsRequested;
                combo.SelectedIndexChanged += list_SelectedIndexChanged;
                cell.Controls.AddAt(0, combo);
                cell.Controls.RemoveAt(1);
            }

   // RadGrid will call this method when the value should
   // be set to the filtering input control(s)
           protected override void SetCurrentFilterValueToControl(TableCell cell)
           {
                base.SetCurrentFilterValueToControl(cell);
                RadComboBox combo = (RadComboBox)cell.Controls[0];
                if ((CurrentFilterValue != string.Empty))
                {
      combo.Text = CurrentFilterValue;
        }
     }

   //
RadGrid will call this method when the filtering value
   // should be extracted from the filtering input control(s)
           protected override string GetCurrentFilterValueFromControl(TableCell cell)
           {
                RadComboBox combo = (RadComboBox)cell.Controls[0];
                return combo.Text;
           }


           protected void list_ItemsRequested(object o, RadComboBoxItemsRequestedEventArgs e)
           {
                // * Below we use the value of field TheDataContext to execute 
                // * a method accesible via the MyCRUD data context for the application.
                using (MyCRUD mc = TheDataContext)         
                {
                     ((RadComboBox)o).DataTextField = DataField;
                     ((RadComboBox)o).DataValueField = DataField;
                     ((RadComboBox)o).DataSource = mc.GetMatchingAddresses(e.Text);
                     ((RadComboBox)o).DataBind();
                }
           }

           private void list_SelectedIndexChanged(object o, RadComboBoxSelectedIndexChangedEventArgs e)
           {
                GridFilteringItem filterItem = (GridFilteringItem)((RadComboBox)o).NamingContainer;
                if ((UniqueName == "Index"))
                {
                    // this is filtering for integer column type
                    filterItem.FireCommandEvent("Filter", new Pair("EqualTo", UniqueName));
                }
                // filtering for string column type
                filterItem.FireCommandEvent("Filter", new Pair("Contains", UniqueName));
           }

      }



Now an instance of the GridBoundColumn class can happily utilize my application's central CRUD class for all its data retrieval operations.


Saturday, July 9, 2011

Create Shortcut to Executable using C#

I needed a C# method to create a shortcut to an executable and place it on the user's desktop in Windows.

I found a method to actually create the shortcut which utilizes the Windows Scripting Host object model. Most examples I found used a separate icon file for the shortcut, whereas I wanted to have the shortcut icon by default be the same one used by the executable itself.

First you must create a reference in Visual Studio to the Windows Script Host Object Model COM object as shown here:



Below is the modified method, where sLinkPathName is the path to the executable.

using IWshRuntimeLibrary

...

private void appShortcutToDesktop(string sLinkPathName)
{
     try
     {
          WshShellClass wsh = new WshShellClass();
          IWshRuntimeLibrary.IWshShortcut scShortcut;

          // Choose the path for the shortcut
          scShortcut = wsh.CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\shorcut.lnk") as IWshRuntimeLibrary.IWshShortcut;

          // Where the shortcut should point to
          scShortcut.TargetPath = txtFile.Text;

          // Description for the shortcut
          scShortcut.Description = "This is a shortcut.";

          // Location for the shortcut's icon
          scShortcut.IconLocation = sLinkPathName + ", 0";

          // Create the shortcut at the given path
          scShortcut.Save();
     }
     catch (Exception ex)
     {
          MessageBox.Show(ex.Message);
     }
} 

Line 22 sets the shortcut's IconLocation property such that it grabs the default icon for the executable, the same one that you'd expect to see if you created the shortcut manually.



Tuesday, April 27, 2010

Create CheckBox Controls Inside A GroupBox Programmatically

I'm working on a WinForms app to interface with SQL server to grab parameters and other info for various objects. It uses a custom control I discovered on CodeProject to create a collapsible GroupBox control.

Say that I want to create a bunch of new controls based on the output of some SQL function or stored procedure. For example, the system stored procedure sp_databases returns a list of all databases on a given SQL server. 

In my collapsible GroupBox, I might want to create a CheckBox control for each database so that I can let the user choose which database to work on in the current session of the application.

To facilitate this, some pseudocode might be helpful:
  • Instantiate a new CheckBox object.
  • Does my GroupBox contain any other CheckBoxes?
    • NO: Set the CheckBox location so that it appears in the upper-left corner of the GroupBox
    • YES: Grab the X and Y coordinates of the last CheckBox contained in the GroupBox
  • Would the width of an additional CheckBox exceed that of the GroupBox?
    • YES: Set the new CheckBox X coordinate so that it aligns with the first CheckBox in the GroupBox, then bump the Y coordinate down by a set value.
    • NO: Place the new CheckBox to the right of the previous one.
  • Set the Text property of the newly-added CheckBox to a given input string value.

Along these lines, I created the method below, which takes a string as input representing the Text property of the newly-created CheckBox.

       
/// <summary>
        /// Create a new CheckBox control within a collapsible GroupBox, assigning input sName
        /// to the Text property.
        /// </summary>
        /// <param name="sName"></param>
        /// <returns></returns>
        private CheckBox CreateNewCheckBox(string sName)
        {
            int iExistingCheckBoxX = 0;
            int iExistingCheckBoxY = 0;

            int iIncrementX = 100;
            int iIncrementY = 20;

            CheckBox cbNew = new CheckBox();

            cbNew.Width = iIncrementX;

            if (cgbDatabases.Controls.Count == 0)
            {
                cbNew.Location = new Point(cgbDatabases.Location.X + 15, cgbDatabases.Location.Y - 50);
            }
            else
            {
                // Existing checkboxes, so get the Location of the last one.
                iExistingCheckBoxX = cgbDatabases.Controls[cgbDatabases.Controls.Count - 1].Location.X;
                iExistingCheckBoxY = cgbDatabases.Controls[cgbDatabases.Controls.Count - 1].Location.Y;

                // If the new control would overshoot the end of the container, bump it down.
                if ((iExistingCheckBoxX + iIncrementX) + cbNew.Width >= cgbDatabases.Width)
                {
                    iExistingCheckBoxX = cgbDatabases.Location.X + 15;
                    iExistingCheckBoxY = iExistingCheckBoxY + iIncrementY;

                    cbNew.Location = new Point(iExistingCheckBoxX, iExistingCheckBoxY);
                }
                else
                {
                    cbNew.Location = new Point(iExistingCheckBoxX + iIncrementX, iExistingCheckBoxY);
                }
            }

            // Set the Text property according to the input.
            cbNew.Text = sName;

            return cbNew;
        }


In the constructor of my WinForm app, as a test I used the collapsible GroupBox control's Add method in conjunction with the new method to insert a bunch of child CheckBox controls into parent GroupBox. 

        public frmMain()
        {
            InitializeComponent();

            cgbDatabases.Controls.Add(CreateNewCheckBox("CheckBox1"));
            cgbDatabases.Controls.Add(CreateNewCheckBox("CheckBox2"));
            cgbDatabases.Controls.Add(CreateNewCheckBox("CheckBox3"));
            cgbDatabases.Controls.Add(CreateNewCheckBox("CheckBox4"));
            cgbDatabases.Controls.Add(CreateNewCheckBox("Checkbox5"));
            cgbDatabases.Controls.Add(CreateNewCheckBox("Checkbox6"));
            cgbDatabases.Controls.Add(CreateNewCheckBox("Checkbox7"));
            cgbDatabases.Controls.Add(CreateNewCheckBox("Checkbox8"));
            cgbDatabases.Controls.Add(CreateNewCheckBox("Checkbox9"));
            cgbDatabases.Controls.Add(CreateNewCheckBox("Checkbox10"));
            cgbDatabases.Controls.Add(CreateNewCheckBox("Checkbox11"));
        }


The results are as I expect:




Advantages of this method include the ability to tweak the variables within the CreateNewCheckBox method to determine what the starting X and Y coordinates will be based on the Location of the GroupBox; if I move the GroupBox somewhere else in my form's design view, the code won't care, it will simply churn out the CheckBox objects based on the parent control's current position at runtime. Also, it prevents new objects from being created outside the visible width of the GroupBox.

Shortcomings include a lack of checking the height of the GroupBox; if a zillion controls are created within it, there's currently no logic to prevent them from being placed in the nonvisible area of the control. Also, I'm currently not analyzing the incoming string parameter to see whether I want to constrain the resulting object to a uniform height or width, which means a CheckBox with a huge label likely will not display its Text value correctly.

Speaking of dimensions, the method is currently not "smart" enough to roll with the punches in terms of variations in height or width of the resulting controls; it doesn't offer an easy way to make the child objects conform to specific patterns (e.g. the objects appear one after the next from left to right, not up to down or diagonally or some other order). These would need to be tweaked and tested manually to ensure the object labels remain intact, and the objects themselves remain visible and usable. A more elegant solution would be to have the method scrutinize the control to be created and its attributes and compensate.

Baby steps, but nonetheless I found this a helpful exercise in creating CheckBox controls at will within a parent GroupBox, and already am seeing ways in which I can improve this implementation. I wish to thank Jordan Hammond, creator of the CollapsibleGroupBox control from the article I cited above, and also Manoli's code formatter, which was used here to make the C# excerpts presentable.