K-3D 8 Released!

Hey all,

For those of you who want to work with 3D drawing and animation and can’t afford to buy one of the expensive 3D programs, K-3D is 8 just released.

Get it here:
http://www.k-3d.org/downloads


How to add a dynamic image and/or a dynamic button to a DataGrid row using a DataGridTemplateColumn and a DataTemplateSelector?

How to add a dynamic image and/or a dynamic button to a row using WPFToolKit DataGrid and DataGridTemplateColumns?

To start, I have a WPF project in Visual Studio 2008. I have installed the WPFToolKit and have added a reference to it in my project.

Often you want to display a DataGrid, but you don’t want to simply display it as is, you want to be able to enhance it and add functionality to it, such as adding an image to the start of each row or adding a button on each row.

Ok, so I have a table created using a DataTable that looks as follows:

IntVal StrVal
0 normal
1 warning
2 error

I am passing this to a WFPToolKit DataGrid.

As I pass this to a Datagrid I want to add two columns:

  1. I want to add an image that is different if it is normal, warning, or error.
  2. I want to add a button only if it is warning or error.

So the visual would look as follows:

Image IntVal StrVal Action
0 normal
1 warning
2 error

Step 1. Install prerequisites: Install Visual Studio 2008, and download and install the WPFToolkit.

You probably already have this done, and there are no steps for provided for these.

Step 2. Create a new WPF project in Visual studio 2008 and design the WPF interface

So once my project was created and the reference to WPFToolKit added, I then changed the XAML on my default Window1 class.

  1. I needed to add a reference to the toolkit here as well.
  2. I needed to add resources for my button.
  3. I needed to add three separate resources for my images.
  4. I needed to add a DataGrid.

Window1.xaml

<Window x:Class="DataGridAddButtonAndImageColumns.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wpftk="http://schemas.microsoft.com/wpf/2008/toolkit"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <DataTemplate x:Key="FixThisTemplate">
            <Button Name="mButtonFixThis" Click="ButtonFixThis_Click">Fix This</Button>
        </DataTemplate>
        <DataTemplate x:Key="NormalTemplate">
        </DataTemplate>
        <DataTemplate x:Key="StatusTemplateNormal" x:Name="mNormalImage">
            <Image Width="16" Height="16" Source="C:\Users\jbarneck\Documents\QuickTests\DataGridAddButtonAndImageColumns\DataGridAddButtonAndImageColumns\bin\Debug\Normal.png" />
        </DataTemplate>
        <DataTemplate x:Key="StatusTemplateWarning" x:Name="mWarningImage">
            <Image Width="16" Height="16" Source="C:\Users\jbarneck\Documents\QuickTests\DataGridAddButtonAndImageColumns\DataGridAddButtonAndImageColumns\bin\Debug\Warning.png" />
        </DataTemplate>
        <DataTemplate x:Key="StatusTemplateError" x:Name="mErrorImage">
            <Image Width="16" Height="16" Source="C:\Users\jbarneck\Documents\QuickTests\DataGridAddButtonAndImageColumns\DataGridAddButtonAndImageColumns\bin\Debug\Error.png" />
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <wpftk:DataGrid Name="mDataGrid" ItemsSource="{Binding}" CanUserAddRows="False" IsReadOnly="True"></wpftk:DataGrid>
    </Grid>
</Window>

Step 3 – Create the data

The data can come from anywhere but for this basic example, I am just statically creating a DataTable in the Constructor.  I also added a property for the DataTable and the DataTable.DefaultView.

Data.cs

using System.Data;

namespace DataGridAddButtonAndImageColumns
{
    public class Data
    {
        #region Member Variables
        private DataTable mTable;
        #endregion

        #region Constructors

        /*
		 * The default constructor
 		 */
        public Data()
        {
            mTable = new DataTable();
            mTable.Columns.Add("IntVal", typeof(int));
            mTable.Columns.Add("StrVal", typeof(string));
            DataRow row0 = mTable.NewRow();
            row0["IntVal"] = 0;
            row0["StrVal"] = "normal";
            mTable.Rows.Add(row0);

            DataRow row1 = mTable.NewRow();
            row1["IntVal"] = 1;
            row1["StrVal"] = "warning";
            mTable.Rows.Add(row1);

            DataRow row2 = mTable.NewRow();
            row2["IntVal"] = 2;
            row2["StrVal"] = "error";
            mTable.Rows.Add(row2);

        }

        #endregion

        #region Properties
        public DataTable Table
        {
            get { return mTable; }
            set { mTable = value; }
        }

        public DataView View
        {
            get { return mTable.DefaultView; }
        }
        #endregion

        #region Functions
        #endregion

        #region Enums
        #endregion
    }
}

Step 4 – Create a ViewModel that implements INotifyPropertyChanged.

So creating a ViewModel is not exactly required but there really is benefit to the Model-View-ViewModel design pattern, so I will attempt to follow it even though this is a simple example application.

  1. I created a new object called DataViewModel.
  2. I implemented the INotifyPropertyChanged interface (though for this small application it isn’t used, I don’t want to leave it out cause you might need it for your application.)
  3. I changed the constructor to take the Data object I designed in the previous step.
  4. I expose the Table and the Table’s view as properties.

DataViewModel.cs

using System;
using System.ComponentModel;
using System.Data;

namespace DataGridAddButtonAndImageColumns
{
    public class DataViewModel : INotifyPropertyChanged
    {
        #region Member Variables
        readonly Data mData;
        #endregion

        #region Constructors

        /*
		 * The default constructor
 		 */
        public DataViewModel(Data inData)
        {
            mData = inData;
        }

        #endregion

        #region Properties
        public DataView View
        {
            get { return mData.View; }
        }

        public DataTable Table
        {
            get { return mData.Table; }
        }
        #endregion

        #region Functions

        #endregion

        #region Enums
        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }
}

Step 5 – Add code to pass the DataTable to the DataGrid

So in the Window1.xaml.cs file, I create a new DataViewModel object and pass it a new Data object.  I then assign the DataTable to the DataGrid’s DataContext object. My class now looks as follows.

Window1.xaml.cs

using System.Windows;
using System.Windows.Controls;

namespace DataGridAddButtonAndImageColumns
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {

        #region Member Variables
        #endregion

        #region Contructor
        public Window1()
        {
            InitializeComponent();
            DataViewModel model = new DataViewModel(new Data());

            // It is ok to pass either the DataTable or the DataView
            // so both lines below work, however I am only using one:
            //
            // mDataGrid.DataContext = model.View;
            // mDataGrid.DataContext = model.Table;

            mDataGrid.DataContext = model.Table;
        }
        #endregion

        #region Functions
        private void ButtonFixThis_Click(object sender, RoutedEventArgs e)
        {
            // Do something here
        }
        #endregion

        #region Properties
        #endregion
    }
}

Now I can compile and run see my simple DataGrid.

IntVal StrVal
0 normal
1 warning
2 error

Step 6 – Create the DataTemplateSelectors

I am going to use two DataTemplateSelector and I want them to share a base class, so first, I am going to create a base class for them.

  1. I inherit DataTemplateSelector.
  2. I add a function to find the parent Window1 object.

BaseDataTemplateSelector.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace DataGridAddButtonAndImageColumns
{
    public class BaseDataTemplateSelector : DataTemplateSelector
    {
        #region Member Variables
        #endregion

        #region Constructors
        /*
		 * The default constructor
 		 */
        public BaseDataTemplateSelector()
        {
        }
        #endregion

        #region Properties
        #endregion

        #region Functions
        protected Window1 GetWindow1(DependencyObject inContainer)
        {
            DependencyObject c = inContainer;
            while (true)
            {
                DependencyObject p = VisualTreeHelper.GetParent(c);

                if (c is Window1)
                {
                    //mSectionControl = c;
                    return c as Window1;
                }
                else
                {
                    c = p;
                }
            }
        }
        #endregion
    }
}

Now I create an ActionDataTemplateSelector and a StatusImageDataTemplateSelector.

The ActionDataTemplateSelector will overload the SelectTemplate function and correctly select the Fix button resource if the status is warning or error.

ActionDataTemplateSelector.cs

using System.Data;
using System.Windows;

namespace DataGridAddButtonAndImageColumns
{
    public class ActionDataTemplateSelector : BaseDataTemplateSelector
    {
        #region Constructors
        /*
		 * The default constructor
 		 */
        public ActionDataTemplateSelector()
        {
        }
        #endregion

        #region Functions
        public override DataTemplate SelectTemplate(object inItem, DependencyObject inContainer)
        {
            DataRowView row = inItem as DataRowView;

            if (row != null)
            {
                Window1 w = GetWindow1(inContainer);
                if (row.DataView.Table.Columns.Contains("IntVal"))
                {
                    if ((int)row["IntVal"] > 0)
                    {
                        return (DataTemplate)w.FindResource("FixThisTemplate");
                    }
                }
                return (DataTemplate)w.FindResource("NormalTemplate");
            }
            return null;
        }
        #endregion
    }
}

The StatusImageDataTemplateSelector also overloads the SelectTempate function and selects the correct image for the status.

StatusImageDataTemplateSelector .cs

using System.Data;
using System.Windows;

namespace DataGridAddButtonAndImageColumns
{
    public class StatusImageDataTemplateSelector : BaseDataTemplateSelector
    {
        #region Constructors

        /*
		 * The default constructor
 		 */
        public StatusImageDataTemplateSelector()
        {
        }
        #endregion

        #region Functions
        public override DataTemplate SelectTemplate(object inItem, DependencyObject inContainer)
        {
            DataRowView row = inItem as DataRowView;

            if (row != null)
            {
                if (row.DataView.Table.Columns.Contains("IntVal"))
                {
                    Window1 w = GetWindow1(inContainer);
                    int status = (int)row["IntVal"];
                    if (status == 0)
                    {
                        return (DataTemplate)w.FindResource("StatusTemplateNormal");
                    }
                    if (status == 1)
                    {
                        return (DataTemplate)w.FindResource("StatusTemplateWarning");
                    }
                    if (status == 2)
                    {
                        return (DataTemplate)w.FindResource("StatusTemplateError");
                    }
                }
            }
            return null;
        }
        #endregion
    }
}

Step 7 – Create functions that add the new columns and have the constructor call each function.

Each function must:

  1. Create a new DataGridTemplateColumn.
  2. Assign a string for the Header.
  3. Create a new DataTemplateSelector and assign it to the DataGridTemplateColumn’s CellTemplateSelector.
  4. Add the new DataGridTemplateColumn to the DataGrid.
        public void CreateActionButtonColumn()
        {
            DataGridTemplateColumn actionColumn = new DataGridTemplateColumn { CanUserReorder = false, Width = 85, CanUserSort = true };
            actionColumn.Header = "Action";
            actionColumn.CellTemplateSelector = new ActionDataTemplateSelector();
            mDataGrid.Columns.Add(actionColumn);
        }

        public void CreateStatusColumnWithImages()
        {
            DataGridTemplateColumn statusImageColumn = new DataGridTemplateColumn { CanUserReorder = false, Width = 85, CanUserSort = false };;
            statusImageColumn.Header = "Image";
            statusImageColumn.CellTemplateSelector = new StatusImageDataTemplateSelector();
            mDataGrid.Columns.Insert(0, statusImageColumn);
        }

Don’t forget to call the functions in the constructor.

        public Window1()
        {
            InitializeComponent();
            DataViewModel model = new DataViewModel(new Data());

            // It is ok to pass either the DataTable or the DataView
            // so both lines below work, however I am only using one:
            //
            // mDataGrid.DataContext = model.View;
            // mDataGrid.DataContext = model.Table;

            mDataGrid.DataContext = model.Table;
            CreateActionButtonColumn();
            CreateStatusColumnWithImages();
        }

Ok, so now you are finished. This should be working for you if you compile and run the program.

Image IntVal StrVal Action
0 normal
1 warning
2 error

Options for handling the images without using a static path

The images were called statically in the above example, however, that will be problematic in actual implementation as each program is installed in a different location and the install location can usually be chosen by a user. You have two options to resolve this, and I will show you how to do both:

  1. Embedding your images
  2. Using image files located in a relative path

Either option work.  The second option makes branding a little easier as code doesn’t have to be recompiled with new images to change the images, because the image files can simply be replaced.

Embedding your images
So you can embed your images as resources and use the embedded resources instead. To embed them, do this:

  1. In Visual Studio under your project, create a folder called Images.
  2. Copy your images into that folder.
  3. In the XAML, change each of the image resource lines as shown
            <Image Width="16" Height="16" Source="Images\Warning.png" />

Using image files located in a relative path
I decided to NOT embed my images but instead solve this by using a relative path. My preference is for the images to come from actual files in an images directory that is relative to the directory from which the executable is launched:

\MyFolder\
\MyFolder\program.exe
\MyFolder\Images\
\MyFolder\Images\Normal.png
\MyFolder\Images\Warning.png
\MyFolder\Images\Error.png

So in order to use relative paths, I found that I could create another object that inherits IValueConverter.

Here is what I had to do to create this:

  1. Create a new class called PathConverter.
  2. Make it inherit IValueConverter
  3. Implement the IValueConverter interface.
  4. Add code to the Convert function.
  5. Cast the “value” parameter to a DataRowView as each DataRow will be the calling object that is passed in as “value”.
  6. Get the relative path using System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location).
  7. Get the status value from the DataRowView and add a couple of if statements that return the relative + the image file path.
using System;
using System.Data;
using System.Globalization;
using System.Windows.Data;

namespace DataGridAddButtonAndImageColumns
{
    public class PathConverter : IValueConverter
    {
        #region Constructors
        /*
		 * The default constructor
 		 */
        public PathConverter()
        {
        }
        #endregion

        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            DataRowView row = value as DataRowView;
            if (row != null)
            {
                if (row.DataView.Table.Columns.Contains("IntVal"))
                {
                    String workingDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                    int status = (int)row["IntVal"];
                    if (status == 0)
                    {
                        return workingDirectory + @"Images\Normal.png";
                    }
                    if (status == 1)
                    {
                        return workingDirectory + @"Images\Warning.png";
                    }
                    if (status == 2)
                    {
                        return workingDirectory + @"Images\Error.png";
                    }
                }
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new System.NotImplementedException();
        }
        #endregion
    }
}

Ok, I am not done yet.  I now needed to edit the XAML again.  here is what we do to the XAML:

  1. I add an xmlns reference to load the local namespace.
  2. I add in the windows resources and instance of the PathConverter.
  3. I change the Image Source value to: Source=”{Binding Converter={StaticResource ImagePathConverter}}”
<Window x:Class="DataGridAddButtonAndImageColumns.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wpftk="http://schemas.microsoft.com/wpf/2008/toolkit"
    xmlns:local="clr-namespace:DataGridAddButtonAndImageColumns"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <local:PathConverter x:Key="ImagePathConverter" />
        <DataTemplate x:Key="FixThisTemplate">
            <Button Name="mButtonFixThis" Click="ButtonFixThis_Click">Fix This</Button>
        </DataTemplate>
        <DataTemplate x:Key="NormalTemplate">
        </DataTemplate>
        <DataTemplate x:Key="StatusTemplateNormal" x:Name="mNormalImage">
            <Image Width="16" Height="16" Margin="3,0" Source="{Binding Converter={StaticResource ImagePathConverter}}" />
            <!--<Image Width="16" Height="16" Source="Images\Normal.png" />--><!-- Embedded -->
        </DataTemplate>
        <DataTemplate x:Key="StatusTemplateWarning" x:Name="mWarningImage">
            <Image Width="16" Height="16" Margin="3,0" Source="{Binding Converter={StaticResource ImagePathConverter}}" />
            <!--<Image Width="16" Height="16" Source="Images\Warning.png" />--><!-- Embedded -->
        </DataTemplate>
        <DataTemplate x:Key="StatusTemplateError" x:Name="mErrorImage">
            <Image Width="16" Height="16" Margin="3,0" Source="{Binding Converter={StaticResource ImagePathConverter}}" />
            <!--<Image Width="16" Height="16" Source="Images\Error.png" />--><!-- Embedded -->
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <wpftk:DataGrid Name="mDataGrid" ItemsSource="{Binding}" CanUserAddRows="False" IsReadOnly="True"></wpftk:DataGrid>
    </Grid>
</Window>

Ok, now we should be done.

Make sure to create the Images folder and add the images in the location where you exectuable runs. You may have to add the images folder to both the debug and release directories or otherwise resolve this, else you will get an exception when the images are not found.

Note: I wrote an improved version of this article and published it here:
http://www.codeproject.com/KB/WPF/AddImageToColumnDynamicly.aspx


Copyright ® Rhyous.com – Linking to this page is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.


Are you using BSD or Linux and you don't even know it?

Hello everyone,

I have had two Open Source experiences with average non-geeks that I would like to share.

Experience 1 – The in-laws are using Linux
I spent Easter at my in-laws and while I was their I of course took some time to “fix” their computers. Doing some maintenance to their computers is a regular task for me. However, they had recent purchased a new netbook and it was the only computer that they didn’t need me to work on.

“You got a new Netbook?”, I asked in surprise. Not that they consult me before every purchase but I usually hear about it. “Can I see it?” I asked.

My father-in-law, a retired seminary teacher who does real estate on the side, went and got the new little Netbook.

I booted it up and while the average person couldn’t tell it was running Linux, I immediately recognized the KDE interface despite the fact that it was tweaked to look as much like windows as possible.

I pressed “Ctrl + Alt + Backspace and sure enough Xorg restarted.

The Netbook is a pretty cool system. It is featured more like a smart phone than a computer, in that it has a tabbed window and you have a limited amount of icons on each tab, including needed items such as a browser, a documentation suite (Google Docs), etc…

My son’s grandparents are using Linux and they don’t even know it. While my curiosity told me to figure out how to enable the root account and start hacking around, I pushed aside the temptation because it was pleasure enough to know that my predictions are coming true.

I said, “By 2010, Linux will be above the watermark of requirements for the majority of users, and will start taking the market by storm.” And I am telling you it has begun.

Well, you might argue that this one purchase by my grandparents doesn’t mean this is true.

Well, I would retort that it isn’t just this one incident.

  • Netbooks are very popular and selling fairly well among all walks of life, not just to my grandparents.
  • There are many Google phones that are running Android, based on the Linux kernel.
  • Slashdot has a story where Ubuntu is claiming 12 million users and Fedora claims 24 million.
  • My company, LANDesk, continues to get an increased amount of request to support Linux flavors.

Experience 2 – A friend of a friend needing to compile an open source app on OS X
My favorite Operating System is FreeBSD, which has a great desktop version PC-BSD. While these are not exactly Linux, they are open source and actually more free than Linux (see my post on licenses). The rise in the use of FreeBSD and PC-BSD is also increasing rapidly.

Windows is the most used operating system by far. Did you know that the second most used operating system is FreeBSD-based. Yes, Macintosh users, underneath the hood of your pretty graphical user interface (GUI), you have a system that is derived in a large amount from FreeBSD.

Yes, if you are running OS X, you are running a system that is, underneath the hood, very similar to FreeBSD. It has a nice ports system called MacPorts that is a very similar system to FreeBSD’s ports system.

Well, as a replacement for a Visio diagram, I used the program Dia so that some of my friends could have the ability to modify and change the diagram (which happens about once a quarter) as desired without spending way too much for Visio when they otherwise would never ever use it. Well, a friend of a friend called me and wanted to use it.

Unfortunately at this time, Dia doesn’t have a version for OS X, but can be installed using MacPorts. So I found myself showing the average user how to install MacPorts. Unfortunately, I don’t have a Mac, so I couldn’t write a walk-thru of doing this and I don’t know if the friend of a friend was successful in installing Dia on OS X, but still, this average user wanted to do it and wanted this open source app that was available to him only because his system was derived in large part from FreeBSD.


A status hander object that keeps the worst status

Ok, so I have an object that is to be compared to a default value and based on the comparison has a status of either normal (0), warning (1), or error (2). Of course, it has an array of child objects that each can also be normal, warning, or error. This parent object should have the status that is the worst or greatest.

So I wrote an object caled StatusHandler.cs that does this in C#. It is simple.

/*Copyright 2010 Jared Barneck All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY Jared Barneck ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are those
 * of the authors and should not be interpreted as representing official policies,
 * either expressed or implied, of Jared Barneck.
 */

namespace StatusHandler
{
    /*
     * The purpose of this class is to hold the worst result
     * received when comparing values in a multicolum row.
     */
    public class StatusHandler
    {
        #region Member Variables
        private CompareResult mResult = CompareResult.Normal;
        #endregion

        #region Constructors

        /*
		 * The default constructor
 		 */
        public StatusHandler()
        {
        }

        public StatusHandler(CompareResult inResult)
        {
            mResult = inResult;
        }

        #endregion

        #region Properties

        public CompareResult Result
        {
            get { return mResult; }
            // Don't allow setting, this should be
            // done by the AddResult function;
        }
        #endregion

        #region Functions
        /*
         *
         */
        public void AddResult(CompareResult inResult)
        {
            // Once an error, always an error
            if (Result == CompareResult.Error)
            {
                return;
            }
            // If a warning, only change the value
            // If the new value is an error.
            if (Result == CompareResult.Warning)
            {
                if (inResult == CompareResult.Error)
                {
                    mResult = inResult;
                }
                return;
            }
            // If result is not an error or warning, then
            // it is most efficient just to set the new
            // value to the incoming value.
            mResult = inResult;
        }

        /*
         * Sets the status back to normal
         */
        public void Reset()
        {
            mResult = CompareResult.Normal;
        }
        #endregion

        #region Enums
        public enum CompareResult
        {
            Normal = 0,
            Warning,
            Error
        }
        #endregion
    }
}

How to use DataTable.Select() when the DataColumn.ColumnName contains a space?

I have a DataColumn that contains an space and I just couldn’t get the DataTable.Select(“Column Name=value) function to work.

So i found a solution on some other guys wordpress blog here.

The answer should be obvious to those who use SQL. In SQL to use a space, it often adds square brackets around the column names. [Column Name]. Yes, using square brackets is the solution.

String colName = "Column Name";
String Value = "some data";
DataTable.Select("[" + colName + "]='" + value + "'");

GhostBSD: A FreeBSD desktop that uses GNOME

Hey all,

I was recently made aware of a new distribution of FreeBSD called GhostBSD. One of the focuses of GhostBSD is to provide a FreeBSD-based desktop that uses GNOME.

I’ll be honest, I like KDE over GNOME and probably always will, but my opinion is not your opinion, and I have heard plenty of opinions amongst FreeBSD users that GNOME is preferred by them. So this is going to be a good thing for those of you who prefer GNOME.

They have released their first amd64 version, which I downloaded and installed to my VMWare environment. Here is a screen shot.


See larger image.

I was pleased to find that it was a Live CD, as well, until I realized that it was a Live CD only. There are such a large number of people who have asked about a FreeBSD distro that focus on the desktop using GNOME, that I was actually disappointed to find out that it does not install to the hard drive. However, if this distribution becomes popular, I am sure that the distribution could eventually include an installer.

It downloads and fits on one CD (not DVD) and so the download was rather quick for me.

I installed to my VMWare environment, however, the keyboard didn’t work. Maybe the i386 version would work. It might be worth detecting why this didn’t work and submitting a bug to GhostBSD. It would also be cool if they provided a version that had vmware-tools installed. I am not sure if I could install vmware-tools to a Live CD and if I did, it would probably only be installed until I rebooted.

Great work GhostBSD team. As FreeSBIE is discontinued according to Distrowatch, I will definitely replace my Live CD version of FreeBSD and GhostBSD may be an excellent option.


For those who don't know how to use Google: 10 Simple Google Search Tricks

Here is an article by Simon Mackie that gives 10 Simple Google Search Tricks for those of you who don’t know how to do anything more than type something into Google and click search. With a few more skills, you can get much better search results.

Quote: I’m always amazed that more people don’t know the little tricks you can use to get more out of a simple Google search. Here are 10 of my favorites.

http://webworkerdaily.com/2010/04/01/10-simple-google-search-tricks/


An article on the iPad from the NY Times: Looking at the iPad From Two Angles

Looking at the iPad From Two Angles

This article is pretty cool in that it reviews the iPad from two angles: from the “techie” angle and from the “non-techie” angle, which is pretty cool. It mentioned that there is a strong polarization to either hate the iPad or be a fan of it.

The haters tend to be techies; the fans tend to be regular people.

Therefore, no single write-up can serve both readerships adequately. There’s but one solution: Write separate reviews for these two audiences.

Read more…


NYTIMES: Growth of Unpaid Internships May Be Illegal, Officials Say

With job openings scarce for young people, the number of unpaid internships has climbed in recent years, leading federal and state regulators to worry that more employers are illegally using such internships for free labor.

Convinced that many unpaid internships violate minimum wage laws, officials in Oregon, California and other states have begun investigations and fined employers.

…many employers failed to pay even though their internships did not comply with the six federal legal criteria that must be satisfied for internships to be unpaid.

Read more: http://www.nytimes.com/2010/04/03/business/03intern.html?src=me&ref=general


Differences between the BSD/FreeBSD Copyrights and the GNU Public License (GPL)

The FreeBSD Copyright and the BSD Copyright

You may notice that FreeBSD uses the term Copyright while GNU uses the term License.
http://www.freebsd.org/copyright/copyright.html

The FreeBSD Copyright is free as in you don’t have to buy a license but you can do pretty much anything. The BSD Copyright is almost the same.

What you can do:

  1. Use it at home for no cost.
  2. Use it at work for no cost.
  3. Use it at work for a publicly accessible server that you make money on for no cost.
  4. Add or change code at no cost.
  5. Distribute the entire source code at no cost.
  6. Distribute the entire source code with your changes at no cost.
  7. Build binaries at no cost.
  8. Distribute binaries with your source at no cost if you also give it away at no cost.
  9. Distribute binaries without also distributing the original source and your changes.
  10. Write code that uses or links to this code and license your new code however you want.
  11. Embed the binaries in software you sell, at no cost, even if you don’t provide the source.

Note: This list was created by me based on my understanding of what people would want to do with the code.

Do I need a lawyer?
No. Basically, there is almost no instance in which you have to pay a fee to anybody to use a FreeBSD Copyrighted or BSD Copyrighted piece of code.

However, while 100% free in cost to use it, it is not 100% free. Notice I italicized the word almost in the above sentence.

For the FreeBSD Copyright, also known as the New BSD Copyright, there are two requirements you must meet.

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

And for the BSD Copyright, there are four requirements listed, but as mentioned on the BSD Copyright web site, the third requirement is no longer required.

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software must display the following acknowledgement:

This product includes software developed by the University of California, Berkeley and its contributors.

4. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

So you can do anything you want with FreeBSD licenses and BSD licenses at no dollar cost, but you have to spend some time and resources to make sure you display some text as required.

I guess if you didn’t want to follow the 2 or 4 steps, you could find someone to pay so you didn’t have to, but the steps are so simple I doubt anyone would choose to try to license the software to not have to follow these steps.

The The GNU Public License or GPL

The The GNU Public License or GPL is not completely different but yet don’t be fooled. It is not the same and is far more restrictive than most realize. And it is harder to explain or describe, especially since there is GPLv1, GPLv2, GPLv3, and I am not even discussing the LGPL here.

You can get more info here:
A Quick Guide to GPLv3

What you can do:

  1. Use it at home for no cost.
  2. Use it at work for no cost.
  3. Use it at work for a publicly accessible server that you make money on for no cost.
  4. Add or change code at no cost.
  5. Distribute the entire source code at no cost.
  6. Distribute the entire source code with your changes at no cost.
  7. Build binaries at no cost.
  8. Distribute binaries with your source at no cost if you also give it away at no cost.

Do I need a lawyer?
For home use, no.
For a business, yes.

If you are doing anything NOT on the above list, you probably need to involve a lawyer. If you stick to the above list, then no, you probably don’t need a lawyer. However, the GPL is so long and wordy you may need a lawyer to determine if you need a lawyer.

The Difference between the BSD/FreeBSD Copyrights and the The GNU Public License or GPL

The first noticeable difference is that the FreeBSD Copyright is 25 lines (when wrapped at 78 characters with some lines blank due to section separation) while the GPL is 339 lines (when wrapped at 78 characters with some lines blank due to section separation). So it is much more difficult to learn and understand the GPL and there is a higher likelihood to take a wrong step.

The following items were removed these from the GPL’s can-do list because you can’t do them without permission from the author, which most likely will come at a cost but not always. Sometimes, the author will just say, “Yes, you can use it in your proprietary software” and sometimes they will charge a fee. However, even in those instances you probably need to pay a lawyer to draft and agreement and get it signed. However, one problem with GPL is that there are usually many different authors and so obtaining such permission becomes impossible.

  1. Distribute binaries without also distributing the original source and your changes.
  2. Write code that uses or links to this code and license your new code however you want.
  3. Embed the binaries in software you sell, at no cost, even if you don’t provide the source.

Lets put this in a table:

What you can do? BSD/FreeBSD Copyright GNU Public License or GPL
1. Use it at home for no cost. x x
2. Use it at work for no cost. x x
3. Use it at work for a publicly accessible server than you make money on for no cost. x x
4. Add or change code at no cost. x x
5. Distribute the entire source code at no cost. x x
6. Distribute the entire source code with your changes at no cost. x x
7. Build binaries at no cost. x x
8. Distribute binaries with your source at no cost if you also give it away at no cost. x x
9. (Commercial) Distribute binaries without also distributing the original source and your changes. x
10. (Commercial) Write code that uses or links to this code and license your new code however you want. x
11. (Commercial) Embed the binaries, without a license fee, in software you sell, even if you don’t provide the source. x

Conclusion

For use at home or work or school or play
In all practicallity there is no difference to a home user between the BSD/FreeBSD Copyrights and the GPL.

For Free Distribution
There is one slight difference in free distribution. Any code you write that uses GPL code must be GPL too. With the BSD/FreeBSD copyright, that is not the case. If you write software that uses or links to BSD licensed software, you can still choose your own license.

For Commercial and Enterprise Use
This is where the difference mainly resides between these two licenses.

For use internally for an enterprise or any use that doesn’t distribute the code, there is no difference.

However, when it comes to including the code or a binary in software that you sell, you are not free to do so. The BSD/FreeBSD Copyrights are much more business and enterprise friendly.

DISCLAIMER

I am not a lawyer. I am not responsible in any way for the misuse of a license based on this post, even if the post is has some piece of data that is blatantly wrong. It is the responsibility of the user of licensed or copyrighted software to make sure the license agreement or copyright is adhered to properly.


April 1, 2010 – A big life change

Hey all,

As you know, Google has now changed it’s name to Topeka.
http://googleblog.blogspot.com/2010/04/different-kind-of-company-name.html

Many of you may not know this but my wife, Michelle, is an Advertising consultant. Since she has done so well branding her blog, www.alittletipsy.com, Google (now Topeka) has hired her to handle their new Topeka brand. She has the daunting task of making the word Topeka as popular as the word Google.

So of course we have to move to Mountain View, California where Google…sorry, Topeka, Inc…has its headquarters. She will work on this new Topeka brand. Her first goal is to get the phrase “I topeka’d him” into the next romantic comedy to leave Hollywood.

I will become a stay-at-home Dad. This will be a great blessing for me. I will be volunteering a few hours a day at the local High School as a consultant for the organization called TWNSS (Teachers With No Social Skills). As a long time geek who has struggled to overcome social skills issues, I can now use my experiences to help others.

It is going to be a big life change.

Please congratulate my wife and I. We will miss our friends in Utah.


K-3D 0.8.0.0 is not yet released but it is now compiling and working on FreeBSD 8

K-3D 0.8.0.0 is not yet released but it is now compiling and working on FreeBSD 8…I hope to help update the port as soon as the final source is released.

The developers at K-3D are great. So I have been working with the developers at K-3D to get things working well for FreeBSD 8 on their new version. They have been patient and willing to work with me. There have been some bumps, but it is now working pretty well.

Anybody who is working in 3D animation should check out K-3D. If you are looking for a free 3D animation program, it doesn’t get better. I tried other open source 3D applications and didn’t find them any where near as easy to use nor anywhere near as intuitive. I also have it running on Windows 7.

One of the coolest features about K-3D is the ability to have a scripted tutorial. It is not just a video, it actually moves your mouse and really demonstrates using the application. Go to Help and select Tutorials and choose the “Creating a mug” tutorial and watch it move your mouse and really create a 3D mug.

If you have used or maybe after you read this post you decide to use K-3D, then take a moment and either buy some swag from them or donate a few bucks to them.

You can find a small gallery here: http://www.k-3d.org/wiki/Still_Gallery.


A snippet for handling each native type in C# and Visual Studio…when generics won't work.

So sometimes you have to have a function that can do something to any native type.

Below are two snippets to speed up the coding for you.

Ok, so of course there are times when you can use Generics.

public class myclass<T>
{
	myclass(T inT)
	{
		// your class
	}
}

However, there are functions that don’t work with a generic type T.

public class myclass<T>
{
	myclass(T inT1, T inT2)
	{
		if (inT1 < inT2)
		{
			// do something
		}
	}
}
&#91;/sourcecode&#93;

This results in an error:   Error 1 Operator '<&#39; cannot be applied to operands of type &#39;T&#39; and &#39;T&#39;.

Maybe you need to handle all the native data types.  So it is annoying to type them in, so I created an iftype snippet.

Create a file called iftype.snippet in this directory: C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC#\Snippets\1033\Visual C#\
Copy in this source and save the file.

&#91;sourcecode language="csharp"&#93;
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>iftype</Title>
			<Shortcut>iftype</Shortcut>
			<Description>Code snippet for an automatically implemented an 'if' statement for each native type.</Description>
			<Author>Jared Barneck</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>
			<Declarations>
				<Literal>
					<ID>varName</ID>
					<ToolTip>Variable name</ToolTip>
					<Default>t</Default>
				</Literal>
			</Declarations>
			<Code Language="csharp"><!&#91;CDATA&#91;
				if ($varName$.Equals(typeof(bool)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Byte)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Char)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(DateTime)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Decimal)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Double)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Int16)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Int32)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Int64)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(SByte)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Single)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(String)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(TimeSpan)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(UInt16)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(UInt32)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(UInt64)))
                {
					throw new NotImplementedException();
                }
$end$&#93;&#93;>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

However, you prefer a switch statement to an if statement. Here is the same thing using the switch statement.

Create a file called switchtype.snippet in this directory: C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC#\Snippets\1033\Visual C#\
Copy in this source and save the file.

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>switchtype</Title>
			<Shortcut>switchtype</Shortcut>
			<Description>Code snippet for an automatically implemented a switch statement for each native type.</Description>
			<Author>Jared Barneck</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>a
			<Declarations>
				<Literal>
					<ID>varName</ID>
					<ToolTip>Variable name</ToolTip>
					<Default>varName</Default>
				</Literal>
			</Declarations>
			<Code Language="csharp"><!&#91;CDATA&#91;
			Type t = $varName$;
            switch (t.ToString())
            {
                case "System.Boolean":
                    throw new NotImplementedException();
                    break;
                case "System.Byte":
                    throw new NotImplementedException();
                    break;
                case "System.Char":
                    throw new NotImplementedException();
                    break;
                case "System.DateTime":
                    throw new NotImplementedException();
                    break;
                case "System.Decimal":
                    throw new NotImplementedException();
                    break;
                case "System.Double":
                    throw new NotImplementedException();
                    break;
                case "System.Int16":
                    throw new NotImplementedException();
                    break;
                case "System.Int32":
                    throw new NotImplementedException();
                    break;
                case "System.Int64":
                    throw new NotImplementedException();
                    break;
                case "System.SByte":
                    throw new NotImplementedException();
                    break;
                case "System.Single":
                    throw new NotImplementedException();
                    break;
                case "System.String":
                    throw new NotImplementedException();
                    break;
                case "System.TimeSpan":
                    throw new NotImplementedException();
                    break;
                case "System.UInt16":
                    throw new NotImplementedException();
                    break;
                case "System.UInt32":
                    throw new NotImplementedException();
                    break;
                case "System.UInt64":
                    throw new NotImplementedException();
                    break;
            }
$end$&#93;&#93;>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

My source uses subversion and has a .svn directory in each subdirectory, how do I remove those .svn directories in Windows?

My source uses subversion and has a .svn directory in each subdirectory, how do I remove those .svn directories?

Method 1 – Exporting with TortoiseSVN
Well, if you are in windows with Tortoise SVN installed, you can right-click on the folder or inside the folder in white space and choose TortoiseSVN | Export. This allows you to select a folder and export your code without the .svn folders.

Method 2 – Scripted deletion
However, if you don’t have a Tortoise SVN Client but you have all those .svn folders, you can easily delete them by a simple one line command from the windows command prompt:

c:\path\to\source> for /F “tokens=*” %A in (‘dir /S /B /AD *.svn’) DO rmdir /S /Q “%A”

Windows 7 speech recognition

Today I am writing this post using windows seven speech recognition.

I turned on windows speech recognition and found a surprisingly working well at times.

You must speak very clearly and be prepared to make a lot of corrections.

To turn on Windows 7 speech recognition, go to Start | All Programs | Accessories | Ease of access | Windows Speech recognition.

Say “Press pipe” to insert a pipe symbol.

…using the keyboard now…
I couldn’t quite finish it using just audio. I struggled selecting the Categories…everything else I was able to do. It is quite difficult and takes a lot of practice and a lot of corrections, but I have to say that I am impressed. However, as impressed as I am, it is a long way from being faster that a keyboard for me. Of course, I have about 20 to 25+ years experience typing and I don’t remember when I started to use a mouse, but only a short few hours of voice, so maybe if I gave this voice thing 25 years I would be just as good…