Question

Does anyone have a complete list of LINQPad extension methods and methods, such as

.Dump()

SubmitChanges()
Was it helpful?

Solution

LINQPad defines two extension methods (in LINQPad.Extensions), namely Dump() and Disassemble(). Dump() writes to the output window using LINQPad's output formatter and is overloaded to let you specify a heading:

typeof (int).Assembly.Dump ();
typeof (int).Assembly.Dump ("mscorlib");

You can also specify a maximum recursion depth to override the default of 5 levels:

typeof (int).Assembly.Dump (1);              // Dump just one level deep
typeof (int).Assembly.Dump (7);              // Dump 7 levels deep
typeof (int).Assembly.Dump ("mscorlib", 7);  // Dump 7 levels deep with heading

Disassemble() disassembles any method to IL, returning the output in a string:

typeof (Uri).GetMethod ("GetHashCode").Disassemble().Dump();

In addition to those two extension methods, there are some useful static methods in LINQPad.Util. These are documented in autocompletion, and include:

  • Cmd - executes a shell command or external program
  • CreateXhtmlWriter - creates a text writer that uses LINQPad's Dump() formatter
  • SqlOutputWriter - returns the text writer that writes to the SQL output window
  • GetMyQueries, GetSamples - returns a collection of objects representing your saved queries / samples (for an example, execute a search using Edit | Search All)
  • Highlight - wraps an object so that it will highlight in yellow when Dumped
  • HorizontalRun - lets you Dump a series of objects on the same line

LINQPad also provides the HyperLinq class. This has two purposes: the first is to display ordinary hyperlinks:

new Hyperlinq ("www.linqpad.net").Dump();
new Hyperlinq ("www.linqpad.net", "Web site").Dump();
new Hyperlinq ("mailto:user@domain.com", "Email").Dump();

You can combine this with Util.HorizontalRun:

Util.HorizontalRun (true,
  "Check out",
   new Hyperlinq ("http://stackoverflow.com", "this site"),
  "for answers to programming questions.").Dump();

Result:

Check out this site for answers to programming questions.

The second purpose of HyperLinq is to dynamically build queries:

// Dynamically build simple expression:
new Hyperlinq (QueryLanguage.Expression, "123 * 234").Dump();

// Dynamically build query:
new Hyperlinq (QueryLanguage.Expression, @"from c in Customers
where c.Name.Length > 3
select c.Name", "Click to run!").Dump();

You can also write your own extension methods in LINQPad. Go to 'My Queries' and click the query called 'My Extensions'. Any types/methods that define here are accessible to all queries:

void Main()
{
  "hello".Pascal().Dump();  
}

public static class MyExtensions
{
  public static string Pascal (this string s)
  {
    return char.ToLower (s[0]) + s.Substring(1);
  }
}

In 4.46(.02) new classes and methods have been introduced:

  • DumpContainer (class)
  • OnDemand (extension method)
  • Util.ProgressBar (class)

Additionally, the Hyperlinq class now supports an Action delegate that will be called when you click the link, allowing you to react to it in code and not just link to external webpages.

DumpContainer is a class that adds a block into the output window that can have its contents replaced.

NOTE! Remember to .Dump() the DumpContainer itself in the appropriate spot.

To use:

var dc = new DumpContainer();
dc.Content = "Test";
// further down in the code
dc.Content = "Another test";

OnDemand is an extension method that will not output the contents of its parameter to the output window, but instead add a clickable link, that when clicked will replace the link with the .Dump()ed contents of the parameter. This is great for sometimes-needed data structures that is costly or takes up a lot of space.

NOTE! Remember to .Dump() the results of calling OnDemand in the appropriate spot.

To use it:

Customers.OnDemand("Customers").Dump(); // description is optional

Util.ProgressBar is a class that can show a graphical progressbar inside the output window, that can be changed as the code moves on.

NOTE! Remember to .Dump() the Util.ProgressBar object in the appropriate spot.

To use it:

var pb = new Util.ProgressBar("Analyzing data");
pb.Dump();
for (int index = 0; index <= 100; index++)
{
    pb.Percent = index;
    Thread.Sleep(100);
}

OTHER TIPS

Besides the well-known myQuery.Dump("Query result:"), another feature to mention is the Util class: It contains many quite handy methods (some of them I've mentioned, but there are a lot more).

Also interesting is that you can easily modify the way Dump() works.

Finally I'll show you how you can make changes permanent (i.e. insert, update, delete LINQ queries) using SubmitChanges() or SaveChanges() as well as how you can access the internal connection object of LinqPad.

And to round it up, I'll show you how you can create simple 2d graphic inside of LinqPad (drawing lines, bitmaps or functions).

So, here's a collection of built in LinqPad features (from my own experience with the tool):


.Dump()

(parameters available in LinqPad v5.03.08 and above)

All LinqPad users know and love the sophisticated .Dump() extension method, which consumes and prints (almost) everything.

But did you know there are a couple of parameters available? Take a look at this code snippet:

var obj=new { a="Hello", b=5, c="World", d=new { y=5, z=10 } };
obj.Dump(description: "1st example", depth: 5, toDataGrid: false, exclude: "b,d");
obj.Dump("2nd example", exclude: "a,c");
obj.Dump("2nd example", exclude: "+b,d"); // new in V5.06.06 beta

The 1st example prints only variables a and c and hides b and d, the 2nd example does the opposite (note that it specifies only 2 of the available parameters). The variablesy and z cannot be hidden individually, because they are not at the top level.

The following parameters are available (all are optional):

  • description [string] - provides a description for the object to dump
  • depth [int?] - limits how deep the objects are recursively inspected
  • toDataGrid [bool] - if true, the output is formatted as a datagrid rather than as RichText
  • exclude [string] - if you provide a comma-separated list of variables, they will be excluded from the output (in the example "a,c": b and d are shown, a and c are hidden)
  • exclude [string] with "+" prefix - the prefix inverts the logic of the exclude parameter. This means, if you provide a comma-separated list of variables, all except the ones specified are hidden (in the example "+b,d": b and d are shown, all others hidden)
  • store included and excluded properties in a variable (new since LinqPad V5.09.04):
    var x=Util.ToExpando(obj, "a, c", "b, d"); x.Dump();
    The first string contains a list of properties to include, the second string a list to exclude
  • expand on click: If you use .OnDemand("click me").Dump(); instead of .Dump(), it will display a link you can click on to expand. Useful if you want to inspect values, e.g. Util.OnDemand("Customer-ID: " + customerObject.ID.ToString(), ()=>customerObject, false).Dump(); to always show the ID per default but reveal the details of customerObject only if you're interested in.

More advanced topics about Dump can be found here.


Environment

This is not a LinqPad extension, but rather a .NET class, but since it is useful, I'll mention it anyway. You can get a lot of useful information you can use in your scripts such as :

Environment.UserDomainName.Dump();
Environment.MachineName.Dump();
Environment.UserName.Dump();
Environment.CurrentDirectory.Dump();
Environment.SystemDirectory.Dump();

N.B. For obtaining Domain\UserName I would use System.Security.Principal.WindowsIdentity.GetCurrent().Name
rather than Environment.UserDomainName+@"\"+Environment.UserName.


Util.WriteCsv

(new: available since LinqPad version v4.45.05 (beta))

Util.WriteCsv (Customers, @"c:\temp\customers.csv");

This will write the content of the table Customers to the CSV file c:\temp\customers.csv. You can also find a nice example how to use Util.WriteCsv and then display the CSV data in Linqpad's result window here.

Hints:

  • To get/create a CSV file which is in the same directory as the query, you can use:
    var csvFile=Util.CurrentQueryPath.Replace(".linq", ".csv");

  • If the table is large, use ObjectTrackingEnabled = false; before you write the CSV to avoid caching it in memory.

  • If you want to output a table in XML format rather than as comma-separated file, you can do it like:

    var xmlFile=Util.CurrentQueryPath.Replace(".linq", ".xml");
    var xml = XElement.Load(xmlFile);
    var query =
      from e in xml.Elements()
      where e.Attribute("attr1").Value == "a"
      select e;
    query.Dump();
    

    This example returns all elements having the attribute attr1 which contains the value "a" from an XML file which has the same name as the query and is contained in the same path. Check out this link for more code samples.


Util.GetPassword

var pwd = Util.GetPassword("UserXY");

This will retrieve the password from LinqPad's built in password manager. To create & change the password, open the "Password manager" menu item in the "File" menu of LinqPad. If there is no such password saved when you run the C# code, a password dialog will open up asking you for the password and you have the choice to create and save it on the fly by checking the save password checkbox (in the example, the password for "UserXY" would be saved, and later on you can find this entry in the Password manager).

Advantages are that you can store the password in the LinqScripts you create securely, separately and encrypted in Windows' user profile (it is stored in %localappdata%\LINQPad\Passwords as a file). LinqPad uses Windows DPAPI to protect the password.

Also, the password is stored centrally, so if you need to change it, you can do it in the menu and it immediately applies to all scripts you've created.

Notes:

  • If you don't want to save the password and just bring up a password dialog, you can use the 2nd parameter as follows:
    var pwd = Util.GetPassword("UserXY", true);
    This will uncheck the save password checkbox in the password dialog (however, the user is still able to check it and choose to save anyway).

  • If you require the password to be stored in a SecureString, you can use this helper function (n.b.: to get the extension method .ToSecureString() used, please follow this link at Stackoverflow - it also allows you to convert it back if needed):
    System.Security.SecureString GetPasswordSecure(string Name, bool noDefaultSave=true)
    {
      return Util.GetPassword(Name, noDefaultSave).ToSecureString();
    }


Util.Cmd

This method works like a command processor. You can invoke all commands you know from the Windows console.

Example 1 - dir:

Util.Cmd(@"dir C:\");

This will output the result of the directory without the need to .Dump it. Storing it in a variable has the advantage that you can use further Linq queries on it. For example:

var path=@"C:\windows\system32"; 
var dirSwitch="/s/b";
var x=Util.Cmd(String.Format(@"dir ""{0}"" {1}", path, dirSwitch), true);
var q=from d in x 
        where d.Contains(".exe") || d.Contains(".dll")              
        orderby d
    select d;
q.Dump();

This will dump all files with file extensions ".exe" or ".dll" contained in C:\windows\system32. The /s switch is used to recurse all subdirectories and /b is used for bare output format. Note that the second parameter of the Cmd method is specified to suppress the console output in order to show only the filtered result using the Dump method.

You can see that this is more flexible than the wildcards you have with dir since you can use the full flexibility of Linq's query engine.

Example 2 - text editor:

You can open a file in Notepad like this:

var filePath=@"C:\HelloWorld.txt";
Util.Cmd(@"%systemroot%\system32\notepad.exe", filePath);

Util.Image

Displays images from an URL. Example:

var url = "http://chart.apis.google.com/chart?cht=p3&chd=s:Uf9a&chs=350x140&chl=January|February|March|April";
Util.Image(url).Dump();

Util.ProgressBar, Util.Progress

Using Util.ProgressBar allows you to display a progress bar. You can use the following helper class:

public class ProgressBar
{
    Util.ProgressBar prog;

    public ProgressBar() 
    { 
        Init("Processing"); 
    }

    private void Init(string msg)
    {
        prog = new Util.ProgressBar (msg).Dump();
        prog.Percent=0;
    }

    public void Update(int percent)
    {
        Update(percent, null);
    }   

    public void Update(int percent, string msg)
    {
        prog.Percent=percent;
        if (String.IsNullOrEmpty(msg))
        {
            if (percent>99) prog.Caption="Done.";
        }
        else
        {
            prog.Caption=msg;
        }
    }
}

Simply use it as the following example shows:

void Main()
{
    var pb1= new ProgressBar();
    Thread.Sleep(50);
    pb1.Update(50, "Doing something"); Thread.Sleep(550);
    pb1.Update(100); Thread.Sleep(50);
}

You can alternatively use Util.Progress to update LinqPads integrated progress bar, for example:

Util.Progress = 25; // 25 percent complete

The difference is that it will not display in the results window, and you can't assign a message to it.


Util.RawHtml

Displays HTML in the output window. Example:

Util.RawHtml (new XElement ("h1", "This is a big heading")).Dump();

Hyperlinq, Util.HorizontalRun

You can use this example function

public void ShowUrl(string strURL, string Title)
{
    Action showURL = delegate() { Process.Start("iexplore.exe", strURL); };
    var url = new Hyperlinq(showURL, "this link", true);
    Util.HorizontalRun (true, "Click ", url, " for details.").Dump(Title);
}

to show hyperlinks in the result window - or any actions like opening your favourite editor. Usage:

ShowUrl("http://stackoverflow.com", "Check out StackOverflow");

Note that this function always works, while new Hyperlinq ("http://myURL", "Web site").Dump(); does not work for some kind of URLs (especially, if you have to pass port names like ":1234" as part of the URL).


Util.ReadLine

Reads input from the console. Example:

int age = Util.ReadLine<int> ("Enter your age");

As a synonym for Util.ReadLine<string>(), you can use Console.ReadLine() as well.

But there is more! You can create a simple JSON parser with the following snippet - quite useful, for example if you want to parse and test a JSON string on the fly. Save the following snippet as JSONAnalyzer.linq using a text editor and then open it in LinqPad (this is to add the references easily on the fly):

<Query Kind="Program">
    <Reference>&lt;RuntimeDirectory&gt;\System.Web.Extensions.dll</Reference>
    <Namespace>System.Web.Script.Serialization</Namespace>
</Query>

void Main()
{
    var jsonData=Util.ReadLine<string>("Enter JSON string:");
    var jsonAsObject = new JavaScriptSerializer().Deserialize<object>(jsonData);
    jsonAsObject.Dump("Deserialized JSON");
}

Now you can run it and simply paste a JSON string from the clipboard into the console - it will use the Dump function to display it as an object nicely - and you also get the error messages of the parser on the screen to fix issues. Very useful for debugging AJAX.

JSON


Util.ClearResults

If you need to clear the results window inside your script, use:

Util.ClearResults();

Either use it at the beginning of your script, or - if you're running multiple queries in a script - you should wait for user input before blanking the screen (e.g. by preceding it with Util.ReadLine).


Custom .Dump() - ICustomMemberProvider

Also interesting is, that you can influence the output of the .Dump() method. Simply implement the interface ICustomMemberProvider, e.g.

public class test : ICustomMemberProvider 
{

      IEnumerable<string> ICustomMemberProvider.GetNames() {
        return new List<string>{"Hint", "constMember1", "constMember2", "myprop"};
      }

      IEnumerable<Type> ICustomMemberProvider.GetTypes() 
      {
        return new List<Type>{typeof(string), typeof(string[]), 
            typeof(string), typeof(string)};
      }

      IEnumerable<object> ICustomMemberProvider.GetValues() 
      {
        return new List<object>{
        "This class contains custom properties for .Dump()", 
        new string[]{"A", "B", "C"}, "blabla", abc};
      }

      public string abc = "Hello1"; // abc is shown as "myprop"
      public string xyz = "Hello2"; // xyz is entirely hidden
}

If you create an instance of this class, like

var obj1 = new test();
obj1.Dump("Test");

then it will output only Hint, constMember1, constMember2, and myprop, but not property xyz:

Linqpad dump


Displaying a MessageBox or InputBox in LinqPad

If you need to display a messagebox, look here how to do it.

For example, you can display an InputBox by using the following code

void Main()
{
    string inputValue="John Doe"; 
    inputValue=Interaction.InputBox("Enter user name", "Query", inputValue);
    if (!string.IsNullOrEmpty(inputValue)) // not cancelled and value entered
    {
        inputValue.Dump("You have entered;"); // either display it in results window
        Interaction.MsgBox(inputValue, MsgBoxStyle.OkOnly, "Result"); // or as MsgBox
    }
}

(don't forget to press F4 and add Microsoft.VisualBasic.dll and its namespaces to make this work)


Util.Run

(new: available since LinqPad version v4.52.1 (beta))

Allows you to run another LINQPad script from within your script or within your own .NET program or Windows service (by referencing the LINQPad4-AnyCPU version of LINQPad.exe). It executes the script just as the command line tool lprun.exe would do it.

Examples:

const string path=@"C:\myScripts\LinqPad\";
var dummy=new LINQPad.QueryResultFormat(); // needed to call Util.Run
Util.Run(path+"foo.linq", dummy);

This example runs the script foo.linq, which contains the following sample code:

void Main(string[] args)
{
    #if CMD
       "I'm been called from lprun! (command line)".Dump();
    #else
       "I'm running in the LINQPad GUI!".Dump();
       args = new[] { "testhost", "test@foo.com", "test@foo.com", "Test Subject" };
    #endif
    args.Dump("Args");
}

It allows you to distinguish if the script was run from inside the LinqPad GUI or via lprun.exe or with Util.Run.

Note: The following variants of invocation might be helpful:

Util.Run(path+"foo.linq", dummy).Dump(); // obviously dumps the script output!
Util.Run(path+"foo.linq", dummy).Save(path+"foo.log"); // writes output into log
Util.Run(path+"foo.linq", dummy).SaveAsync(path+"foo1.log");     // async output log

SubmitChanges() - Linq To SQL

If you're using LinqToSQL, you might want to make changes permanent (for insert/update/delete operations). Since the database context is implicitly made by LinqPad, you need to call SubmitChanges() after each change as shown below.

Examples for (LinqPad-)Northwind database:

Insert

var newP = new Products() { ProductID=pID, CategoryID=cID, 
            ProductName="Salmon#"+pID.ToString() };
Products.InsertOnSubmit(newP);
SubmitChanges();    

Update

var prod=(from p in Products
            where p.ProductName.Contains("Salmon")
            select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
SubmitChanges(); 

Delete

var itemsToDelete=Products.Where(p=> p.ProductName.Contains("Salmon") ||
    p.ProductName.Contains("Trout"));
foreach(var item in itemsToDelete) { Products.DeleteOnSubmit(item); }
SubmitChanges();

Note: In order to get valid IDs for the previous examples, you can use:

var cID = (from c in Categories 
            where c.CategoryName.Contains("Seafood") 
            select c).FirstOrDefault().CategoryID;

var pID = Products.Count()+1;

before you invoke them.


SaveChanges() - Entity Framework

If you're using Entity Framework, you might want to make changes permanent as well (for insert/update/delete operations). Since the database context is implicitly made by LinqPad, you need to call SaveChanges() after each change as shown below.

The examples are basically the same as before for LinqToSQL, but you need to use SaveChanges() instead, and for inserting and deleting the methods have changed as well.

Insert

var newP = new Products() { ProductID=pID, CategoryID=cID, 
            ProductName="Salmon#"+pID.ToString() };
Products.Add(newP);
SaveChanges();  

Update

var prod=(from p in Products
            where p.ProductName.Contains("Salmon")
            select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
SaveChanges(); 

Delete

var itemsToDelete=Products.Where(p=> p.ProductName.Contains("Salmon") ||
    p.ProductName.Contains("Trout"));
foreach(var item in itemsToDelete) { Products.Remove(item); }
SaveChanges();

Note: In order to get valid IDs for the previous examples, you can use:

var cID = (from c in Categories 
            where c.CategoryName.Contains("Seafood") 
            select c).FirstOrDefault().CategoryID;

var pID = Products.Count()+1;

before you invoke them.


this - database context

In LinqPad, the database context is established automatically by using the combobox at the top and picking the right database for your query. But sometimes, it is useful to reference it explicitly, for example if you copy some code from your project out of Visual Studio, and paste it into LinqPad.

Your code snippet taken from the Visual Studio project very likely looks like this:

var prod=(from p in dc.Products
            where p.ProductName.Contains("Salmon")
            select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
dc.SaveChanges(); 

Now what to do with dc? Of course, you could remove every occurrence of dc. in your query, but it is much easier. Just add

var dc=this; // UserQuery

to the top of your snippet like so:

void Main()
{
    var dc=this;
    var prod=(from p in dc.Products
                where p.ProductName.Contains("Salmon")
                select p).FirstOrDefault();
    prod.ProductName="Trout#"+prod.ProductID.ToString();
    dc.SaveChanges(); 
}   

and the code will work instantly!


this.Connection

Using LinqPad with OleDb, converting a datatable to Linq object, SQL queries in Linq

The following code snippet helps you to use LinqPad with OleDb. Add System.Data.OleDb from the System.Data assembly to the query properties, then paste the following code into Main():

var connStr="Provider=SQLOLEDB.1;"+this.Connection.ConnectionString; 

OleDbConnection conn = new OleDbConnection(connStr);
DataSet myDS = new DataSet();
conn.Open();

string sql = @"SELECT * from Customers";
OleDbDataAdapter adpt = new OleDbDataAdapter();
adpt.SelectCommand = new OleDbCommand(sql, conn); 
adpt.Fill(myDS);

myDS.Dump();

Now add a SqlServer connection to LinqPad and add the Northwind database in order to run this example.

N.B.: If you just want to get the database and server of the currently selected connection, you can use this code snippet:

void Main()
{
    var dc=this;
    var tgtSrv=dc.Connection.DataSource;
    var tgtDb=dc.Connection.ConnectionString.Split(';').Select(s=>s.Trim())
        .Where(x=>x.StartsWith("initial catalog", StringComparison.InvariantCultureIgnoreCase))
        .ToArray()[0].Split('=')[1];
    tgtSrv.Dump();
    tgtDb.Dump();
}

You can even convert myDS into Linq, the answers to the following question show how to do it: Nice examples of using .NET 4 dynamic keyword with Linq

One more example: Suppose your DBA gives you a SQL query and you want to analyze the results in LinqPad - of course in Linq, not in SQL. Then you can do the following:

void Main()
{
    var dc=this;

    // do the SQL query
    var cmd =
        "SELECT Orders.OrderID, Orders.CustomerID, Customers.CompanyName,"
        +"       Customers.Address, Customers.City"
        +" FROM Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID";
    var results = dc.ExecuteQuery<OrderResult>(cmd);

    // just get the cities back, ordered ascending
    results.Select(x=>x.City).Distinct().OrderBy(x=>x).Dump();
}

class OrderResult
{   // put here all the fields you're returning from the SELECT
    public dynamic OrderID=null; 
    public dynamic CustomerID=null;
    public dynamic CompanyName=null;
    public dynamic Address=null;
    public dynamic City=null;
}

In this example the DBA's SELECT query is just "thrown into" the command text, and the results are filtered and ordered by City.
Of course, this is a simplified example, your DBA would probably support you with a more complex script, but you're getting the idea: Just add a supporting result class which contains all the fields from the SELECT clause and then you can directly use it.
You can even take the result from a stored procedure this way and use it in Linq. As you can see, in this example I don't care about the data type and use dynamic to express it.
So this is really about rapid programming to be able to analyze data quickly. You shouldn't do this in your real application for various reasons (SQL injection, because you can use EF from the beginning etc).


PanelManager

Draw graphic in LinqPad, part 1

To use the examples below, press F4 and add System.Windows.dll, System.Windows.Forms.dll, WindowsFormsIntegration.dll, PresentationCore.dll and PresentationFramework.dll to your LinqPad program and also add the namespace System.Windows.Shapes.

The 1st example simply draws a line:

var myLine = new Line();
myLine.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
myLine.X1 = 1; myLine.X2 = 50;
myLine.Y1 = 1; myLine.Y2 = 50;
myLine.StrokeThickness = 2;
PanelManager.DisplayWpfElement(myLine, "Graphic");

The 2nd example shows how you can display graphic in LinqPad by using the PanelManager. Normally LinqPad only supports Wpf objects. This example uses System.Windows.Forms.Integration.WindowsFormsHost to make a Windows.Forms.PictureBox available (it was inspired by this):

// needs (F4): System.Windows.dll, System.Windows.Forms.dll, 
// WindowsFormsIntegration.dll, PresentationCore.dll, PresentationFramework.dll 
void Main()
{       
    var wfHost1 = new System.Windows.Forms.Integration.WindowsFormsHost();
    wfHost1.Height=175; wfHost1.Width=175; wfHost1.Name="Picturebox1";
    wfHost1.HorizontalAlignment=System.Windows.HorizontalAlignment.Left;
    wfHost1.VerticalAlignment=System.Windows.VerticalAlignment.Top;
    System.Windows.Forms.PictureBox pBox1 = new System.Windows.Forms.PictureBox();
    wfHost1.Child = pBox1;
    pBox1.Paint += new System.Windows.Forms.PaintEventHandler(picturebox1_Paint);
    PanelManager.StackWpfElement(wfHost1, "Picture");
} 

public string pathImg
{
    get { return System.IO.Path.Combine(@"C:\Users\Public\Pictures\Sample Pictures\", 
            "Tulips.jpg"); } 
}

// Define other methods and classes here
public void picturebox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
    // https://stackoverflow.com/a/14143574/1016343
    System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(pathImg);
    System.Drawing.Point ulPoint = new System.Drawing.Point(0, 0);
    e.Graphics.DrawImage(bmp, ulPoint.X, ulPoint.Y, 175, 175);
}

This will create the following graphic (panel items "Graphic" and "Picture" are added by the examples above):

Showing_Graphic_in_LinqPad

If you want to display the images from the Northwind database, you can do the following:
Change the image file name to "NorthwindPics.jpg", then add the following code at the beginning of the 2nd example's Main() method:

var img = (from e in this.Employees select e).FirstOrDefault().Photo.ToArray();
using (FileStream fs1 = new FileStream(pathImg, FileMode.Create))
{
    const int offset=78;
    fs1.Write(img, offset, img.Length-offset);
    fs1.Close();
}

It will read the first record from the Employees table and display the picture.

Check out the following links to find out more:
Shapes and basic drawing in WPF
LinqPad custom visualizers

Note: You can achieve the same without the PanelManager as well, as the following example, which I saw here shows:

// using System.Drawing;
using (var image=new Bitmap(100, 100))
using (var gr = Graphics.FromImage(image))
{
    gr.FillRectangle(Brushes.Gold, 0, 0, 100, 100);
    gr.DrawEllipse(Pens.Blue, 5, 5, 90, 90);
    gr.Save();
    image.Dump();
}

It is using the .Dump() command to display it. You can invoke image.Dump() multiple times and it will append the image.


Windows Forms

Draw graphic in LinqPad, part 2

The following example, inspired by this post, is showing how to implement a simple function plotter in Linqpad 5 using C#7:

void Main()
{
    fnPlotter(x1: -1, x2: 1, fn: (double x) => Math.Pow(x, 3)).Dump();
}

public static Bitmap fnPlotter(double x1=-3, double x2=3, double s=0.05, 
                                   double? ymin=null, double? ymax=null, 
                                   Func<double, double> fn = null, bool enable3D=true)
{
    ymin = ymin ?? x1; ymax = ymax ?? x2;

    dynamic fArrPair(double p_x1 = -3, double p_x2 = 3, double p_s = 0.01, 
                          Func<double, double> p_fn = null)
    {
        if (p_fn == null) p_fn = ((xf) => { return xf; }); // identity as default
        var xl = new List<double>(); var yl = new List<double>();
        for (var x = p_x1; x <= p_x2; x += p_s)
        {
            double? f = null;
            try { f = p_fn(x); }
            finally
            {
                if (f.HasValue) { xl.Add(x); yl.Add(f.Value); }
            }
        }
        return new { Xs = xl.ToArray(), Ys = yl.ToArray() };
    }

    var chrt = new Chart(); var ca = new ChartArea(); chrt.ChartAreas.Add(ca);
    ca.Area3DStyle.Enable3D = enable3D;
    ca.AxisX.Minimum = x1; ca.AxisX.Maximum = x2;   
    ca.AxisY.Minimum = ymin.Value; ca.AxisY.Maximum = ymax.Value;

    var sr = new Series(); chrt.Series.Add(sr);
    sr.ChartType = SeriesChartType.Spline; sr.Color = Color.Red;
    sr.MarkerColor = Color.Blue; sr.MarkerStyle = MarkerStyle.Circle;
    sr.MarkerSize = 2;

    var data = fArrPair(x1, x2, s, fn); sr.Points.DataBindXY(data.Xs, data.Ys); 
    var bm = new Bitmap(width: chrt.Width, height: chrt.Height);
    chrt.DrawToBitmap(bm, chrt.Bounds); return bm;
}

It is using the capability of LinqPad to display Windows forms in the results panel.
Example
Add references (press F4):
System.Drawing.dll, System.Windows.Forms.dll, System.Windows.Forms.DataVisualization.dll
and add all namespaces from these assemblies.


Additional hints / further reading:

  • Want to use LinqPad in Visual Studio? Here's how you can do that.

  • Need to have LinqPad as a "Portable app"? Read here how to do that.

  • Joe's website for LinqPad is always an excellent source. Inside LinqPad, Help -> What's New gives you hints about new functions and methods. The LinqPad Forum also contains helpful hints.

  • Also very helpful: This article about Linq(Pad) debugging.

  • Use lprun.exe for running LINQ queries in your batch scripts. Read this article for more details. For example:
    echo Customers.Take(100) > script.txt
    lprun -lang=e -cxname=CompanyServer.CustomerDb script.txt
    In this example, the query is a simple LINQ expression. Of course, you can prepare complex queries as well using -lang=program to activate the program mode.

  • You can write your own extension methods and store them in the My Queries tab on the left hand side of LinqPad: The last item of the tree is named My Extensions; double click on it to open a file where you can write extensions that are available to all your queries. Simply put them into the public static class MyExtensions, and use the Main() method to include tests for your extensions.

Dump is a global extension method and SubmitChanges comes from the DataContext object which is a System.Data.Linq.DataContext object.

LP adds only Dump and Disassemble as far as I'm aware. Though I would highly recommend opening it in Reflector to see what else is there that can be used. One of the more interesting things is the LINQPad.Util namespace which has some goodies used by LINQPad internally.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top