Dailycode.info

Short solution for short problems

How to add a line break or new line in a SharePoint survey question

A user is trying to make a survey. Now, she needed to create a header for each new page in the survey. She tried to use the textbox and hit enter in the question field, that's what I would do to. And it appears as if the enter are accepted. But when you look at the question, you will notice that the line break disappeared. As I was looking for a solution, I found that in the previous version, this was possible but not in WSS 3.0! So after looking a little more, this site gave a good solution, I decided to use it, but with a slightly different approach.

The thing is that we will implement a javescript that will look for elements with classname : 'ms-formlabel'. Then it will replace the word linebreak with a <BR>. This solution you can find on the site I mentioned above. But they suggest to place a content editor webpart on each page that uses the survey, like the newform.aspx of each survey. Since I'm using a WSS site specially for surveys, I don't want to do this every time I create new survey. So I added the code to the default masterpage of the site. In the head section of the page I placed a function called: setLineBreaks()

<HEAD runat="server">
            …
            <script language="javascript" type="text/javascript">
            function setLinebreaks()
            {
                        var className;
                        className = 'ms-formlabel';
                        
                        var elements = new Array();
                        var elements = document.getElementsByTagName('td');
                        
                        for (var e = 0; e < elements.length; e++)
                        {
                        if (elements[e].className == className){
                        elements[e].innerHTML = elements[e].innerHTML.replace(/linebreak/g,'<br/>');}
                        }
            }
            </script>
</HEAD>

Then I call this function on the pageload event like this (the code I added is in bold):

<BODY scroll="yes" 
onload="javascript:if (typeof(_spBodyOnLoadWrapper) != 'undefined') _spBodyOnLoadWrapper();setLinebreaks();">
 

 

So now every time you enter the word linebreak in a question a new line will be started. (It will be replaced with a <br>)

 

 


How to hide or show space, tab indicators in visual studio

I accidentely pressed a wrong key combination in VS. then the space and tab indication showed up.

I tried looking in the options of the text editor and all environment options but couldn't find the solution. Then I googled and came up with the key combination that does the trick. First press Ctrl-R then press Ctrl-W. You will see the indication go on and off.

 


New layout

I'm expiriencing with a new layout, so expect in the coming days some changes. If it the result is not good, I wil change back to the old style.

I also added some BlogEngine functionality, like a tag cloud, ratings on posts, co-comments, ... If you post a comment without using an avatar, you'll see a picture of my precious daughter appearing.

Hope this improves the readability and the functionality.


Downloads

I created a downloads page because there were several demands for a demo project.

The first download is a demo project of the directshow library. I show how to take a picture and adjust video settings quickly.

Here's a screenshot of the program:

I'm so sorry I didn't shaved. Please forgive me ;-)

Here's the link: http://www.dailycode.net/blog/page/Downloads.aspx

The little picturebox on the top left displays the camera stream, the large one shows the picture you've taken. The reason why I look so funny on the little box is that I'm holdong the webcam in one hand and trying to perform a alt-printscreen with the other hand. :-) The examples above are taken with a Microsoft webcam. As you can see the results are very good. If you have an older webcam, read on, this might help you...

When your camera is not showing up, try lowering the resolution.  

//const int VIDEOWIDTH = 1600; // Depends on video device caps
//const int VIDEOHEIGHT = 1200; // Depends on video device caps
const int VIDEOWIDTH = 640; // Depends on video device caps
const int VIDEOHEIGHT = 480; // Depends on video device caps

I tested the program with a very old webcam, who only supported 640*480. then I adjusted the brightness and this is what it looked like:


Exporting a directory structure

This program is now updated and available as download on this blog, more on this here)
I was looking for a way to export the directory structure of a given directory. I found a simple recursive way to do this. The output is a richhtextbox, where the users can copy paste the structure. This is how it looks (directories are marked in red, files in black):
 
 
I added some features like, show files in structure and to options to show or hide the full file or directory names.
Next the piece of code that does the trick. No fancy stuff, just a simple recursive method that fills a richt text box. First the onlcick event behond the generate button, then the method that generates the directory structure.
 
        private void btnGenerate_Click(object sender, EventArgs e)
        {
            rtxtOutput.Text = "";
            if (!String.IsNullOrEmpty(brwSource.SelectedPath))
            {
                DirectoryInfo searchdir = new DirectoryInfo(brwSource.SelectedPath);
                GetDirStructure(brwSource.SelectedPath, searchdir.FullName);
            }
        }
  
        public void GetDirStructure(string path, string searchdir)
        {
            try
            {
                DirectoryInfo dir = new DirectoryInfo(path);
                
                DirectoryInfo[] subDirs = dir.GetDirectories();
                FileInfo[] files = dir.GetFiles();
                
                int dept = 0;
 
                if (dir.FullName != searchdir)
                {
                    DirectoryInfo parent = dir;
                    while (parent.FullName != searchdir)
                    {
                        parent = parent.Parent;
                        dept++;
                    }
                }
                string deptstring ="  ";
                for (int i = 0; i < dept; i++)
                {
                    deptstring = deptstring + "  ";
                }
                rtxtOutput.SelectionColor = Color.Red;
                if (cbxFull.Checked)
                {
                    rtxtOutput.SelectedText = String.Format("{1}{0}\n", dir.FullName, deptstring);
                }
                else
                {
                    rtxtOutput.SelectedText = String.Format("{1}{0}\n", dir.Name, deptstring);
                }
                rtxtOutput.SelectionColor = Color.Black;
                deptstring = deptstring + "  ";
                if (cbxFiles.Checked)
                {
                    foreach (FileInfo fi in files)
                    {
                        if (cbxFullFile.Checked)
                        {
                            rtxtOutput.SelectedText = String.Format("{1}{0}\n", fi.FullName.ToString(), deptstring);
                        }
                        else
                        {
                            rtxtOutput.SelectedText = String.Format("{1}{0}\n", fi.Name, deptstring);
                        }
                    }
                }
                if (subDirs != null)
                {
                    foreach (DirectoryInfo sd in subDirs)
                    {
                        dept++;
                        GetDirStructure(path + @"\\" + sd.Name, searchdir);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
      }
        }
  
 Here you can download the program:
 

No more int.Parse errors

Some of you may find this a silly post, but only today I discovered that int has a method called int.TryParse. In the past I have written a lot of these checks that can be replaced by the tryparse method. The cool thing about it is that it returns the parsed value (if the parse succeeded) as an out argument. So this post is for all the dummies who didn't found out about this method!

int perc;

if (int.TryParse(value, out perc))

As I looked it up on the Microsoft site, it says that it has been supported since the Framework 2.0:

Version Information

.NET Framework

Supported in: 3.5, 3.0, 2.0

http://msdn.microsoft.com/en-us/library/f02979c7.aspx

A friend of mine posted about this in 2005 here!

I find this very interesting in his post:

The reason why the TryMethod is introduced, is because exceptions are expensive. On codinghorror you find a benchmark tool and you notice that the (default) Parse method is a lot slower.


How to create site definition (template) with a custom masterpage

Today I started to investigate the site definitions again.

It has been a while since I've been there, and lots of things changed since the upgrage to WSS3.0. My first challange was to create a simple site definition. No big problem there. Now I'm configuring this site definition to match the style of the company. So the first thing I had to find out was how to implement a custom masterpage in my site definition.

The masterpages definitions are found in this directory: Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\GLOBAL. By default you will find 2 masterpages, the default.master and the mwsdefault.master. So I copied the default.master and renamed it to MRD.master. This is the first thing you do. Then change some small things in the master page, so you can see if your site template implements the correct master page. Now lets look at the changes you'll have to make in the ONET.xml of the site template.

In every configuration you want to implement the custom master page, you should have set the CustomMasterUrl attribute like this:

<Configuration ID="0" Name="Default" CustomMasterUrl="_catalogs/masterpage/mrd.master">

<Configuration ID="1" Name="Blank" CustomMasterUrl="_catalogs/masterpage/mrd.master">

...

So once the CustomMasterUrl attribute is set , we add the masterpage module to the modules section of each configuration where the CustomMasterUrl attribute is set.

<Modules>

 <Module Name="Default" />

 <Module Name="MRDMasterPage" />

</Modules>

</Configuration>

The last thing we have to do is declare this module on the bottom of the onet.xml, in the modules section:

</Configurations>

<Modules>

 <Module Name="MRDMasterPage" Url="_catalogs/masterpage" SetupPath="global">

  <File Url="MRD.master" Type="GhostableInLibrary" IgnoreIfAlreadyExists="TRUE" />

 </Module>

When you look at the ONET.xml of the MPS site template, you'll find a module called: EnsureMWSMasterPage. This has the property RootWebOnly set to false, so all subsites will have the masterpage copied to them. You can use this module simular as the one I explained on top.

The next thing I'm going to find out is how we can set the theme of the site using site templates.

By the way, changing or creating site templates is not the supported way. But sometimes the only way. Microsoft is providing all kinds of alternatives for altering the site defenitions, but still its powerfull. When you change things and implement them in production, you should have a document where the changes are described in detail. So you can reporduce them after you installed an update.