How to make an array of PictureBoxes in Visual Basic - arrays

How do I make an array of PictureBoxes in Visual Basic?
I'm trying to make a row of PictureBoxes -that's all the same size, and same picture- to display across the form. How could I do this?
I made the array using this:
Dim blk(10) As PictureBox
and the code to place the PictureBoxes is this:
'Create PictureBoxes
blk(0) = blk_Green()
blk(0).Image = imgl_blk.Images(0)
blk(0).Visible = True
blk(0).SetBounds(10, 10, blk_Green.Width, blk_Green.Height)
For i = 1 To 10 Step 1
blk(i) = blk_Green()
blk(i).Image = imgl_blk.Images(0)
blk(i).Visible = True
blk(i).SetBounds(i * 10, 10, blk_Green.Width, blk_Green.Height)'I will change this according to what it needs to be
Next
imgl_blk is an ImageList, and blk_Green is a ImageBox I've already made on the form.
When I run it, only one of the PictureBoxes will show up, instead of all 10 from the array.
This is what i'm trying to get (Or something like this):
This is what happens instead:
How could I make this work? Thanks in advance!

If you want to create a control array:
Dim blk() As PictureBox
blk = New PictureBox() {PictureBox1, PictureBox2, PictureBox3, PictureBox4}
Then you can reference PictureBox1 with blk(0), PictureBox2 with blk(1), PictureBox3 with blk(2) and PictureBox4 with blk(3).

You're assigning the same Object's reference to all 10 PictureBoxes. You need to instantiate each one of your PictureBoxes separately and then assign each one's Image property.
BTW, you should really look into GDI+'s drawing methods such as Graphics.DrawImage() to do this kind of stuff. It would be a lot faster and less of a memory-hog.

You may try this :
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim Shapes(10) As PictureBox
For i = 1 To 10
Shapes(i) = New PictureBox
Shapes(i).Name = "rect" + Str(i)
Shapes(i).BackColor = Color.Green
Shapes(i).Location = New Point(10 + 50 * i, 20)
Shapes(i).Size = New Size(40, 20)
Shapes(i).Visible = True
Me.Controls.Add(Shapes(i))
Next
End Sub
End Class

Related

send data from form 1 to form 2

I have made 2 variables:
Public a as Integer
Public b as Integer
and I have a text field where 2 values can be inserted like this: "1 - 10"
so I split the value and saved them in those 2 variables a and b.
but I need those 2 values in different forms but all I'm getting is 0.
I also created Dim c as form1 = new form1 in the form2.
What's the problem?
Depending on a relation between Form1 and Form2, you can use this kind of communication (this is for a parent-child relation):
Form 2:
Public ParentFrm as Form1
Public a as Int16
Form 1 - in it's running instance:
Public b as Int16
Dim NewInstanceOfForm2 as New Form2
NewInstanceOfForm2.ParentFrm = Me ' this is to ensure you can talk back to correct instance of parent form
NewInstanceOfForm2.a = 12345
NewInstanceOfForm2.BackColor = colors.Pink
NewInstanceOfForm2.TextBox1.Text = "Hello World!!!"
Since we set the ParentFrm in the Form2, you can communicate the same way back and set things in Form1:
ParentFrm.b = 789
ParentFrm.TextBox3 = "Hi there!!!"
ParentFrm.UpdateForm1FromDatabasePublicFunction()
Siblings can communicate through a common parent. But in all the cases, you need to get to understand instances of the forms. Remember, that you can communicate only with objects (TextBox, Button, DataGridView,...) and Public variables of the form.
You could create a module and define the variable as puclic there, that way they'll always be accessible from anywhere on the application.
Right click the solution, Add New, Module
And inside that module add
Public a, b as Integer
To split the textbox input and store them in these vars use
Dim s as String
Dim sp() as String
s = TextBox1.Text
sp = s.Split("-")
This stores the values in the textbox separated by '-' on sp(0) and sp(1) respectively.
You can then stote them into you public variables.
a = sp(0)
b = sp(1)
And call then from any form you need.
Well, i am not sure what it exactly is you want but here are some suggestions:
if your form1 contains two variables like so:
Public a As Integer = 0
Public b As Integer = 0
and you want to retrieve the value of one of those variables from another form, lets say from Form2, then all you need to do is that:
(Put this code in either a function, or an event of your second Form (for example Form2)):
dim current_a As Integer = 0
current_a = Form1.a
dim current_b As Integer = 0
current_b = Form1.b
If you enter the text (for example: "1 - 10“), into a textbox, but want to get both values (in this case 1, and 10), you only need to grab them by for example creating a loop, to search for these values, like so:
dim textbox_str As String = ""
textbox_str = TextBox1.Text
( in this example, the TextBox1.Text would contain "1 - 10")
dim final_str1 As String = ""
dim final_str2 As String = ""
for each s_ As String In textbox_str
If Not s_ = " " Then
final_str1 = final_str1 & s_
Else
Exit For
End If
Next
(after this, final_str1 would contain "1")
(now extract the second number, by doing the following:)
final_str2 = textbox_str.Replace(final_str1 & " - ", "")
(and now, final_str2 would contain "10")
(so you would have both numbers extracted from that text)
As i said, i do not exactly know what you want, but hopefully this helped you, let me know if it is what you were looking for!

What is the most efficient way to extract information from a text file formatted like this

Consider a text file stored in an online location that looks like this:
;aiu;
[MyEditor45]
Name = MyEditor 4.5
URL = http://www.myeditor.com/download/myeditor.msi
Size = 3023788
Description = This is the latest version of MyEditor
Feature = Support for other file types
Feature1 = Support for different encodings
BugFix = Fix bug with file open
BugFix1 = Fix crash when opening large files
BugFix2 = Fix bug with search in file feature
FilePath = %ProgramFiles%\MyEditor\MyEditor.exe
Version = 4.5
Which details information about a possible update to an application which a user could download. I want to load this into a stream reader, parse it and then build up a list of Features, BugFixes etc to display to the end user in a wpf list box.
I have the following piece of code that essentially gets my text file (first extracting its location from a local ini file and loads it into a streamReader. This at least works although I know that there is no error checking at present, I just want to establish the most efficient way to parse this first. One of these files is unlikely to ever exceed more than about 250 - 400 lines of text.
Dim UpdateUrl As String = GetUrl()
Dim client As New WebClient()
Using myStreamReader As New StreamReader(client.OpenRead($"{UpdateUrl}"))
While Not myStreamReader.EndOfStream
Dim line As String = myStreamReader.ReadLine
If line.Contains("=") Then
Dim p As String() = line.Split(New Char() {"="c})
If p(0).Contains("BugFix") Then
MessageBox.Show($" {p(1)}")
End If
End If
End While
End Using
Specifically I'm looking To collate the information about Features, BugFixes and Enhancements. Whilst I could construct what would in effect be a rather messy if statement I feel sure that there must be a more efficient way to do this , possibly involving linq. I'd welcome any suggestions.
I have added the wpf tag on the off chance that someone reading this with more experience of displaying information in wpf listboxes than I have might just spot a way to effectively define the info I'm after in such a way that it could then be easily displayed in a wpf list box in three sections (Features, Enhancements and BugFixes).
Dom, Here is an answer in C#. I will try to convert it to VB.Net momentarily. First, since the file is small, read all of it into a list of strings. Then select the strings that contain an "=" and parse them into data items that can be used. This code will return a set of data items that you can then display as you like. If you have LinqPad, you can test thecode below, or I have the code here: dotnetfiddle
Here is the VB.Net version: VB.Net dotnetfiddle
Imports System
Imports System.Collections.Generic
Imports System.Linq
Public Class Program
Public Sub Main()
Dim fileContent As List(Of String) = GetFileContent()
Dim dataItems = fileContent.Where(Function(c) c.Contains("=")).[Select](Function(c) GetDataItem(c))
dataItems.Dump()
End Sub
Public Function GetFileContent() As List(Of String)
Dim contentList As New List(Of String)()
contentList.Add("sb.app; aiu;")
contentList.Add("")
contentList.Add("[MyEditor45]")
contentList.Add("Name = MyEditor 4.5")
contentList.Add("URL = http://www.myeditor.com/download/myeditor.msi")
contentList.Add("Size = 3023788")
contentList.Add("Description = This is the latest version of MyEditor")
contentList.Add("Feature = Support for other file types")
contentList.Add("Feature1 = Support for different encodings")
contentList.Add("BugFix = Fix bug with file open")
contentList.Add("BugFix1 = Fix crash when opening large files")
contentList.Add("BugFix2 = Fix bug with search in file feature")
contentList.Add("FilePath = % ProgramFiles %\MyEditor\MyEditor.exe")
contentList.Add("Version = 4.5")
Return contentList
End Function
Public Function GetDataItem(value As String) As DataItem
Dim parts = value.Split("=", 2, StringSplitOptions.None)
Dim dataItem = New DataItem()
dataItem.DataType = parts(0).Trim()
dataItem.Data = parts(1).Trim()
Return dataItem
End Function
End Class
Public Class DataItem
Public DataType As String
Public Data As String
End Class
Or, in C#:
void Main()
{
List<string> fileContent = GetFileContent();
var dataItems = fileContent.Where(c => c.Contains("="))
.Select(c => GetDataItem(c));
dataItems.Dump();
}
public List<string> GetFileContent()
{
List<string> contentList = new List<string>();
contentList.Add("sb.app; aiu;");
contentList.Add("");
contentList.Add("[MyEditor45]");
contentList.Add("Name = MyEditor 4.5");
contentList.Add("URL = http://www.myeditor.com/download/myeditor.msi");
contentList.Add("Size = 3023788");
contentList.Add("Description = This is the latest version of MyEditor");
contentList.Add("Feature = Support for other file types");
contentList.Add("Feature1 = Support for different encodings");
contentList.Add("BugFix = Fix bug with file open");
contentList.Add("BugFix1 = Fix crash when opening large files");
contentList.Add("BugFix2 = Fix bug with search in file feature");
contentList.Add("FilePath = % ProgramFiles %\\MyEditor\\MyEditor.exe");
contentList.Add("Version = 4.5");
return contentList;
}
public DataItem GetDataItem(string value)
{
var parts = value.Split('=');
var dataItem = new DataItem()
{
DataType = parts[0],
Data = parts[1]
};
return dataItem;
}
public class DataItem
{
public string DataType;
public string Data;
}
The given answer only focuses on the first part, converting the data to a structure that can be shaped for display. But I think you main question is how to do the actual shaping.
I used a somewhat different way to collect the file data, using Microsoft.VisualBasic.FileIO.TextFieldParser because I think that makes coding just al little bit easier:
Iterator Function GetTwoItemLines(fileName As String, delimiter As String) _
As IEnumerable(Of Tuple(Of String, String))
Using tfp = New TextFieldParser(fileName)
tfp.TextFieldType = FieldType.Delimited
tfp.Delimiters = {delimiter}
tfp.HasFieldsEnclosedInQuotes = False
tfp.TrimWhiteSpace = False
While Not tfp.EndOfData
Dim arr = tfp.ReadFields()
If arr.Length >= 2 Then
Yield Tuple.Create(arr(0).Trim(), String.Join(delimiter, arr.Skip(1)).Trim())
End If
End While
End Using
End Function
Effectively the same thing happens as in your code, but taking into account Andrew's keen caution about data loss: a line is split by = characters, but the second field of a line consists of all parts after the first part with the delimiter re-inserted: String.Join(delimiter, arr.Skip(1)).Trim().
You can use this function as follows:
Dim fileContent = GetTwoItemLines(file, "=")
For display, I think the best approach (most efficient in terms of lines of code) is to group the lines by their first items, removing the numeric part at the end:
Dim grouping = fileContent.GroupBy(Function(c) c.Item1.TrimEnd("0123456789".ToCharArray())) _
.Where(Function(k) k.Key = "Feature" OrElse k.Key = "BugFix" OrElse k.Key = "Enhancement")
Here's a Linqpad dump (in which I took the liberty to change one item a bit to demonstrate the correct dealing with multiple = characters:
You could do it with Regular Expressions:
Imports System.Text.RegularExpressions
Private Function InfoReader(ByVal sourceText As String) As List(Of Dictionary(Of String, String()))
'1) make array of fragments for each product info
Dim products = Regex.Split(sourceText, "(?=\[\s*\w+\s*])")
'2) declare variables needed ahead
Dim productProperties As Dictionary(Of String, String)
Dim propertyNames As String()
Dim productGroupedProperties As Dictionary(Of String, String())
Dim result As New List(Of Dictionary(Of String, String()))
'2) iterate along fragments
For Each product In products
'3) work only in significant fragments ([Product]...)
If Regex.IsMatch(product, "\A\[\s*\w+\s*]") Then
'4) make array of property lines and extract dictionary of property/description
productProperties = Regex.Split(product, "(?=^\w+\s*=)", RegexOptions.Multiline).Where(
Function(s) s.Contains("="c)
).ToDictionary(
Function(s) Regex.Match(s, "^\w+(?=\s*=)").Value,
Function(s) Regex.Match(s, "(?<==\s+).*(?=\s+)").Value)
'5) extract distinct property names, ignoring numbered repetitions
propertyNames = productProperties.Keys.Select(Function(s) s.TrimEnd("0123456789".ToCharArray)).Distinct.ToArray
'6) make dictionary of distinctProperty/Array(Of String){description, description1, ...}
productGroupedProperties = propertyNames.ToDictionary(
Function(s) s,
Function(s) productProperties.Where(
Function(kvp) kvp.Key.StartsWith(s)
).Select(
Function(kvp) kvp.Value).ToArray)
'7) enlist dictionary to result
result.Add(productGroupedProperties)
End If
Next
Return result
End Function

Sorting contents of a listbox

I'm using the following code to add items to a listbox:
Dim i As Integer = 0
Dim temp As String
ListBox2.Items.Clear()
While i <= 9
temp = Str(final_average(i)) + " " + Str(i + 1) + " " + Str(cals(i))
ListBox2.Items.Add(temp)
i = i + 1
End While
I want to sort this using the average or final_average(i), but the following code doesn't seem to work:
Dim arr(ListBox2.Items.Count - 1) As Object
ListBox2.Items.CopyTo(arr, 0)
Array.Sort(arr)
ListBox2.Items.Clear()
ListBox2.Items.AddRange(arr)
How do I sort the contents of the listbox?
(Note: This is not homework but part of a bigger project).
Here is the proper way to do it.
A. First create your list items class.
Public Class MyListItem
Implements IComparable(Of MyListItem)
Public FinalAverage As Integer
Public Number As Integer
Public Cals As Integer
Public Sub New(ByVal finalAverage As Integer, ByVal number As Integer, ByVal cals As Integer)
Me.FinalAverage = finalAverage
Me.Number = number
Me.Cals = cals
End Sub
Public Overrides Function ToString() As String
'' the way you want it to be shown in the listbox.
Return String.Format("{0} {1} {2}", FinalAverage, Number, Cals)
End Function
Public Function CompareTo(ByVal other As MyListItem) As Integer Implements System.IComparable(Of MyListItem).CompareTo
'' the way list items are compared for sorting... Return 0 for equal, -1 for smaller, +1 for bigger
If Me.FinalAverage < other.FinalAverage Then Return -1
If Me.FinalAverage > other.FinalAverage Then Return 1
Return 0
End Function
End Class
B. Now use this class to add items to your listbox.
Dim listItems As New List(Of MyListItem)
For i As Integer = 0 To 9
listItems.Add(New MyListItem(final_average(i), i + 1, cals(i)))
Next
listItems.Sort()
ListBox2.DataSource = listItems
And that's it! :)
I have a rather simpler solution to your problem!
Method 1
1) Sort the items in Listbox1:
We will do this by setting the Sorted property of Listbox1 to True. It will keep your old list which was not sorted safely!
listBox1.Sorted = True
2) Send the items to Listbox2:
Copy all the items from listbox1 to listbox2 by saving it to an object collection. They will move in order, and hence, the second one is sorted from A-Z.
Dim objCollection As Object() = New Object(listBox1.Items.Count - 1)
listBox1.Items.CopyTo(objCollection, 0)
listBox2.Items.AddRange(objCollection)
3) Place items in Listbox1 in proper order:
We have both the listbox with sorted items. Now, all we need to do is to place items in the previous order. As I said, your placement of items will be stored safely, we will retrieve it back by setting the Sorted property of Listbox1 to False.
listBox1.Sorted = False
And, you will get a sorted listbox2!
Method 2
Instead of sorting and then copying and then unsorting listbox1, you can first copy all items to listbox2 and then sort listbox2. In this case, there will be no need of unsorting the first one again!
I hope it works perfectly!

Label with different font sizes

Basically I want to achieve something like this:
but I have no idea how to do it, I tried with 2 labels to combine them but the result isn't that great..
You need to draw the text from a different point of view, namely, the baseline:
Public Class MyLabel
Inherits Label
<Browsable(False)> _
Public Overrides Property AutoSize As Boolean
Get
Return False
End Get
Set(value As Boolean)
'MyBase.AutoSize = value
End Set
End Property
Protected Overrides Sub OnPaint(e As PaintEventArgs)
'MyBase.OnPaint(e)
Dim fromLine As Integer = Me.ClientSize.Height * 0.75
Dim g As Graphics = e.Graphics
Dim fontParts() As String = Me.Text.Split(".")
Using bigFont As New Font(Me.Font.FontFamily, 20)
TextRenderer.DrawText(g, fontParts(0), bigFont, _
New Point(0, fromLine - GetBaseLine(bigFont, g)), _
Me.ForeColor, Color.Empty)
If fontParts.Length > 1 Then
Dim bigWidth As Integer = TextRenderer.MeasureText(g, fontParts(0), bigFont, _
Point.Empty, TextFormatFlags.NoPadding).Width
Using smallFont As New Font(Me.Font.FontFamily, 8)
TextRenderer.DrawText(g, "." & fontParts(1), smallFont, _
New Point(bigWidth + 3, fromLine - GetBaseLine(smallFont, g)), _
Me.ForeColor, Color.Empty)
End Using
End If
End Using
End Sub
Private Function GetBaseLine(fromFont As Font, g As Graphics) As Single
Dim fontHeight As Single = fromFont.GetHeight(g)
Dim lineSpacing As Single = fromFont.FontFamily.GetLineSpacing(fromFont.Style)
Dim cellAscent As Single = fromFont.FontFamily.GetCellAscent(fromFont.Style)
Return fontHeight * cellAscent / lineSpacing
End Function
End Class
The code basically measures the height of the font from a line. In my example, I used the bottom 25% of the Label's client space to say, start drawing from this line: Me.ClientSize.Height * 0.75.
For each font you use, you would have to measure that font's baseline and subtract that from your drawing line in order to offset your drawing position of the text.
Measuring an individual character's dimensions is not easy due to aliasing and glyph overhangs. I added a small padding between the big text and the small text: bigWidth + 3 to try to make it look good. If the big number ends in a 7, the distance looks a little off because the stem of the 7 is angled.
Result:
Create a new class inherited from Label, and override the void OnPaint(PaintEventArgs e) method to change the default rendering behavior:
public class MyLabel : Label
{
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawString("A", Font, new SolidBrush(ForeColor), 10, 10);
e.Graphics.DrawString("B", new Font(Font.FontFamily, 20), new SolidBrush(ForeColor), 50, 10);
}
}
As a result, "B" will be two times larger the "A". You can achieve your goal in the same way, but you have to calculate the position of your sub-strings ("145", ".", "54") and draw them.
Use devexpress LabelControl.AllowHtmlString property to true and use the supported <size> tag within the LabelControl's Text property as detailed in the HTML Text Formatting documentation.
you can use user control WPF in windows form. to do that do this step.
1. add user control to the windows form
2.from xml of usercontrol name grid like t1
3. add this function to the usercontrol.wpf.cs
public void Actor(string text)
{
StringBuilder sb = new StringBuilder();
sb.Append(#"<TextBlock xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'> ");
sb.Append(text);
sb.Append(#"</TextBlock>");
TextBlock myButton = (TextBlock)XamlReader.Parse(sb.ToString());
this.t1.Children.Clear();
t1.Children.Add(myButton);
}
4. after that from form1.css add this function in every where you want.
userControl11.Actor("<Run Text='Hi ' FontWeight='Bold'/><Run Text='Hitler ' FontWeight='Bold'/>");
userControl11.Actor(" < Run FontWeight = 'Bold' FontSize = '14' Text = 'This is WPF TextBlock Example. ' />");
you can mange the write code "" of Actor function by using xml wpf.

Create Video from ImageSource

Is there any easy way of adding ImageSources to a stack and create a video from it?
I already did such a class. I only have to submit my "ImageInfo" which is a system.DrawingBitmap. This can be created easy by using the following code:
Public Function WpfBitmapSourceToBitmap(ByVal source As BitmapSource) As System.Drawing.Bitmap
If source Is Nothing Then Return Nothing
Dim bmp As New System.Drawing.Bitmap(source.PixelWidth, source.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
Dim data As System.Drawing.Imaging.BitmapData = bmp.LockBits(New System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), System.Drawing.Imaging.ImageLockMode.[WriteOnly], System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
source.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride)
bmp.UnlockBits(data)
Return bmp
End Function
Then I did a AviClass to add frames to it and store it as a AVI file with preselected Codec (for example XVid MPEG4)
Public Class clsAviWriter
Inherits MAINInterface.TB.Imaging.Pia7.clsDspTemplate
Private cAvi As AviReaderWriter.AviFile.AviManager
Private AviStream As AviReaderWriter.AviFile.VideoStream
Private AudioStream As AviReaderWriter.AviFile.AudioStream
Private cFps As clsTbQueue
Private OldFpsDate As Date = Now
''' <summary>
''' The image object to paint graphical objects on it
''' </summary>
''' <value>descriptor of the image</value>
Public Overrides Property ImageInfo() As MAINInterface.TB.Imaging.Pia7.clsImageInfo
Get
Return Me._ImageInfo
End Get
Set(ByVal value As MAINInterface.TB.Imaging.Pia7.clsImageInfo)
Me._ImageInfo = value
Call WriteFrame()
Call Me.OnPropertyChanged(Me.Guid)
End Set
End Property
Private Sub WriteFrame()
Dim D As Date = Now
Dim Fps As Single
Me.cFps.Values.Add(D.Subtract(Me.OldFpsDate).Ticks)
Me.OldFpsDate = D
Me.cFps.Trim()
Fps = 1000 / New TimeSpan(Me.cFps.Average).TotalMilliseconds
Me.cFps.BufferSize = TB.Math.myTrim(Fps * 1, 1, 1000)
If Me.AviStream IsNot Nothing Then
Me.AviStream.AddFrame(Me._ImageInfo.Image.Clone)
End If
End Sub
Public Sub New()
Me.ClassDescription = "Write images into an avi file"
Me.cFps = New clsTbQueue(10)
End Sub
Private Sub InitializeAvi()
Dim W As String
Dim Fps As Single
Dim di As New IO.DirectoryInfo(TB.SystemMain.AppPath & "Avi\")
TB.FileSystem.CreateDirectories(di)
W = IO.Path.Combine(di.FullName, "Record_" & Now.Ticks.ToString("0") & ".avi")
Me.cAvi = New AviReaderWriter.AviFile.AviManager(W, False)
Dim Opts As New AviReaderWriter.AviFile.Avi.AVICOMPRESSOPTIONS
Opts.fccType = 0
Opts.fccHandler = 1684633208
Opts.dwKeyFrameEvery = 0
Opts.dwQuality = 0 '0 ... 10000
Opts.dwFlags = 8 'AVICOMRPESSF_KEYFRAMES = 4
Opts.dwBytesPerSecond = 0
Opts.lpFormat = 0
Opts.lpParms = New IntPtr(0)
Opts.cbParms = 3532
Opts.dwInterleaveEvery = 0
Fps = 1000 / New TimeSpan(Me.cFps.Average).TotalMilliseconds
'Dim bm1 As Bitmap
'bm1 = TB.Imaging.CreateReScaledImage(Me.pic.Image, New Size(Me.pic.Image.Width, Me.pic.Image.Height), False)
Me.AviStream = cAvi.AddVideoStream(Opts, Math.Floor(TB.Math.myTrim(Fps, 1, 50)), Me._ImageInfo.Image.Clone)
End Sub
Public Overrides Property Run() As Boolean
Get
Return Me._Run
End Get
Set(ByVal value As Boolean)
If Me._Run <> value Then
Me._Run = value
If Me._Run = True Then
Call InitializeAvi()
Else
If Me.cAvi IsNot Nothing Then
Me.cAvi.Close()
Me.cAvi = Nothing
Me.AviStream = Nothing
End If
End If
Call Me.OnPropertyChanged(Me.Guid)
End If
End Set
End Property
End Class
For more codes look here: http://www.wischik.com/lu/programmer/avi_utils.html and MSDN or http://www.codeproject.com/KB/audio-video/avigenerator.aspx
I've posted the sourcecode to show how such a sequence can looks like (code above need some more references which are not public available). You can see that you just need to initialize, add frames, store the FPS value and safe it to harddisk.
Also if wanted, you can search for DirectShow to see how all works.
You can use
http://joshsmithonwpf.wordpress.com/2008/04/23/good-old-fashion-image-animations-in-wpf/
as an example. Afterwards you can use a screen capture program like snagit or microsoft expression encoder pro to capture it as a video
Josh Smith's blog pointed by Raj here (http://joshsmithonwpf.wordpress.com/2008/04/23/good-old-fashion-image-animations-in-wpf/) is a good example of showing images from a folder in the WPF app.
Once this is working you can look at Saveen Reddy's blog to convert app to video
http://blogs.msdn.com/b/saveenr/archive/2008/09/22/wpf-xaml-saving-an-animation-as-an-avi-video-file.aspx
Use this library avifilewrapper search for the sample code on how to create an avi from bitmaps. This article explains how you can render your visuals to bitmaps. I don't think it will get any easier than that.
Since WPF does not include video encoding libraries, you'll need to lean on an external one to do the encoding. This blog post describes how you can use Windows Media Encoder to do so. Alternatively, you could bundle something like mencoder with your app and start it as an external process that you control and monitor from your app.

Resources