Category Archives: C#

Notes on C# / .NET

Add winform support to a .NET 6,7,8 project

To add winforms support to an .NET class (Windows only) library add <UseWindowsForms>true</UseWindowsForms> to the project file. It will look like something below. (.NET 8.0)

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0-windows</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
   <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>
</Project>


Lastest update in February 2024, inital post in February 2024

Set a different accessibility for properties of an inner-class compared to its outer-class and other classes

In C#, it’s not straightforward to limit access to an inner class from outside its outer class. For instance, if you want to expose an inner class as a property and only allow read access to one of its properties while preventing write access. There are several ways to solve this problem. One method involves using interfaces, which in my opinion, offers a clean solution.

The example below shows how a integer value called MyValue inside MyInnerClass can read publicly but only be set by its outer-class ‘MyOuterClass’.

The code should be self-explanatory.

public class MyOuterClass
{
    //Define the setters to be used in "OuterClass"
    public interface IInnerClass
    {
        //The get will be provided by MyInnerClass,
        //no need to implement it in the interface
        int MyValue { set; }
    }

    public MyInnerClass InnerClass = new MyInnerClass();
    private readonly IInnerClass myInnerClass;

    public MyOuterClass()
    {
        myInnerClass = InnerClass;
    }

    //A method to test access
    void test()
    {
        myInnerClass.MyValue = 123;
    }

    public class MyInnerClass : IInnerClass
    {
        //Used outside OuterClass when OuterClass.InnerClass 
        //properties are called
        public int MyValue { get; private set; }
        // Implement the interface which can have other
        // access specifiers! get is not part of the
        // interface and is provided by MyInnerClass
        // This setter can only be called in MyOuterClass
        int IInnerClass.MyValue { set => this.MyValue = value; }
    }
}

In other parts of the code the code fragment below will yield the error “Error CS0272 The property or indexer ‘MyOuterClass.MyInnerClass.MyValue’ cannot be used in this context because the set accessor is inaccessible”

MyOuterClass c = new MyOuterClass();
c.InnerClass.MyValue = 123;

Lastest update in October 2023, inital post in October 2023

Adding a MDI child directly when opening the application (.NET 6.0)

In .NET 6.0 adding a MDI child only seems to work after the MDI parent is loaded. Therefore add the MDI child creation code in the Shown event handler and all functions correctly.

    private void MDIParent_Shown(object sender, EventArgs e)
    {
       MDIChild child = new MDIChild();
       child.MdiParent = this;
       child.Show();
    }

MDIForm is a standard form, note that the MDIParent form needs the IsMdiContainer property set to true;

Lastest update in February 2023, inital post in February 2023

Add two format methods to TextWriter

Two simple extensions methods to make formatting with the TextWriter class more easier and IMHO easier to read.

static class extensionMethods
{  
   public static void Format(this System.IO.TextWriter writer, string format, 
   params object[] args)
   {
      writer.Write(String.Format(formatInfo, format, args));
   }

   public static void FormatLine(this System.IO.TextWriter writer, string format,
   params object[] args)
   {
      writer.WriteLine(String.Format(formatInfo, format, args));
   }
};

Lastest update in December 2019, inital post in December 2019

Add styled text to RichTextBox

Add a text with a specific font and color to a RichTextBox control.

static class extensionMethods
{
  public static void AppendText(this RichTextBox textBox, string appendText, 
  System.Drawing.Color textColor = null, Font TextFont = null)
  {
      textBox.SelectionStart = textBox.TextLength;
      textBox.SelectionLength = 0;
      if (textColor != null) textBox.SelectionColor = textColor;
      if (textFont != null)  textBox.SelectionFont = textFont;
      textBox.AppendText(appendText);
      textBox.SelectionColor = textBox.ForeColor;
   }
};
Lastest update in December 2019, inital post in December 2019

TryGetValueOrCreate

Get an existing item from a dictionary or create a new value with a default value, using an extension method.

 static class extensionMethods
 {

     public static V TryGetValueOrCreate<K, V>(this Dictionary<K, V> dictionary, K key) 
     where V : new()
    {
       V data;
       if (!dictionary.TryGetValue(key, out data))
       {
          data = new V();
          dictionary.Add(key, data);
       }
       return (data);
    }
 }

The method above can be used using the code below:

public class Item
{
   public int test;
};

Dictionary<int,Item> dict = new Dictionary<int,Item>();
Item item = dict.TryGetValueOrCreate(3);
item.test= 123;

Lastest update in December 2019, inital post in December 2019

Sort a list using a delegate

To sort a list class using a delegate use the code below:

List list = new List();
list.Add(3);
list.Add(2);
list.Add(1);

list.Sort(delegate(int a, int b)
{
	return (a - b);
}
);
Lastest update in September 2017, inital post in September 2017

Datagridview checkbox can’t be checked (Forms)

If a DataGridView with a checkbox column can’t be checked verify whether editing has been
disabled. EditMode set to EditOnKeystrokeOrF2 appears to work OK.

To prevent editing of specific columns, use the CellBeginEdit event or set the ReadOnly property of the column.

private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
}

Also make sure the DataGridView is Enabled and not ReadOnly!

Lastest update in February 2021, inital post in September 2017

DataGridView: detect click on empty cells (Forms)

To detect a mouse click on empty cells add the mouseClick event.

private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
{
            DataGridView.HitTestInfo ht = dataGridView1.HitTest(e.X, e.Y);
            if (ht != null)
            {
		  //e.RowIndex and e.ColumnIndex can be used.
	     }
}       
Lastest update in September 2017, inital post in September 2017

DataGridView: No selection mode (Forms)

To prevent selection in a DataGridView add the SelectionChanged event

private void dataGridView_SelectionChanged(object sender, EventArgs e)
{
	//Just to be sure this will not become recursive 
	if (dataGridView.SelectedRows.Count > 0) dataGridView.ClearSelection();  
}
Lastest update in February 2021, inital post in September 2017