TnTinMN 418 Practically a Master Poster

The DataTable class is definitely not light-weight. But it is easy to configure and I use it a lot for database manipulation. Hence I grabbed what I knew worked and presented it as solution for setting a datasource.

However, for your application, it is not the best choice.

I have done a little research and you can bind to an array, however this "Binding" is a one time event that creates the DataPointCollection. Are far as I can discern, after this intialization, there is no link back to the source data. :(

I still want to create a class that implements the INotifyPropertyChange interface and see that would work.

Since your application will be updating the Y-Values, it is probably best to create the datapoints your self once, and then update their values. This does work.

I want to put names on each column, visible under the X-axix. Now they are simply numbered.

You are currently using the "Label" property; this is typically used to show the value. To place the column label on the X-Axis, use the DataPoint.AxisLable property.

TnTinMN 418 Practically a Master Poster

The short answer to most of your questions is: Yes it can be done.

I prefer to use a DataTable for the data source. Here is an example of how to set the needed properties to produce my interpretation of what you are looking to accomplish. If you have any questions, please do not hesitate to ask them.

using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace Example_Battery_Chart_Csharp
{
    public partial class Form1 : Form
    {

        public BatteryTable Batteries = new BatteryTable(8);
        private System.Windows.Forms.DataVisualization.Charting.Chart bc = new System.Windows.Forms.DataVisualization.Charting.Chart();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            bc.DataSource = Batteries;
            bc.Legends.Clear();

            bc.ChartAreas.Clear();
            bc.ChartAreas.Add("Primary");
            bc.ChartAreas["Primary"].AxisY.Minimum = 0;
            bc.ChartAreas["Primary"].AxisY.Maximum = 100;
            bc.ChartAreas["Primary"].AxisY.Interval = 25;
            bc.ChartAreas["Primary"].AxisY.MajorGrid.Enabled = true;
            bc.ChartAreas["Primary"].AxisY.MajorGrid.Interval = bc.ChartAreas["Primary"].AxisY.Interval;
            bc.ChartAreas["Primary"].AxisY.MinorGrid.Enabled = true;
            bc.ChartAreas["Primary"].AxisY.MinorGrid.Interval = 5;
            bc.ChartAreas["Primary"].AxisY.MinorTickMark.Enabled = true;
            bc.ChartAreas["Primary"].AxisY.MinorTickMark.Interval = 5;
            bc.ChartAreas["Primary"].AxisY.MinorTickMark.TickMarkStyle = TickMarkStyle.AcrossAxis;


            bc.Series.Clear();
            bc.Series.Add("Level");

            bc.Series["Level"].ChartArea = "Primary";
            bc.Series["Level"].ChartType = SeriesChartType.Column;
            bc.Series["Level"].CustomProperties = "DrawingStyle=Cylinder";
            bc.Series["Level"].XValueType = ChartValueType.String;
            bc.Series["Level"].XValueMember = "Name";
            bc.Series["Level"].YValueType = ChartValueType.Int32;
            bc.Series["Level"].YValueMembers = "Level";

            // The next 3 values can be set at the Point level as well
            // Defined here, they become the default values for the Points
            bc.Series["Level"].BackSecondaryColor = Color.White;
            bc.Series["Level"].BackGradientStyle = GradientStyle.TopBottom;
            bc.Series["Level"].Color = Color.BlueViolet;


            bc.Dock = DockStyle.Fill;
            bc.Parent = this;

            // The Customize Event is raised before the chart is drawn
            // At this point the Chart control has created all the labels
            // and points for you.  This gives you the chance to makes any 
            // changes you want.

            bc.Customize += bc_Customize;

            // This is to show …
TnTinMN 418 Practically a Master Poster

Do you have the C# Code? If so, you could reconfigure it as class library and call the download method.

If not, there are two options: 1) Process.WaitForExit and 2) The Process.Exit event.

http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.exited.aspx

TnTinMN 418 Practically a Master Poster

I don't know C++, but it appears as though the structure packs to values into a single Int64 value. if this is the case, try reading the value as a Int64 and masking and bit shifting to get the values.

            Int64 val = 978086288751L;
            Int64 ean = default(Int64);
            Int64 rec_no = default(Int64);

            ean = val & 0x000000ffffffffffL;
            rec_no = Convert.ToInt64(Convert.ToUInt64( val) & 0xffffff0000000000L) >> 40;
TnTinMN 418 Practically a Master Poster

I don't have the Microsoft.Office.Tools.Excel.dll so I can not test the get_Range function, but according to the documentation it returns a Microsoft.Office.Interop.Excel.Range.

The Range object has the "Text" property that returns the as-displayed (formatted) text.

TnTinMN 418 Practically a Master Poster
TnTinMN 418 Practically a Master Poster

If there is no space after the final comma, setting the RemoveEmptyEntries option should work. Here is an example:

   Dim s As String = "1,2,3,4,5,"
   Dim parts() As String = s.Split(","c)
   Stop
   ' will yield 6 entries

   parts = s.Split(New Char() {","c}, StringSplitOptions.RemoveEmptyEntries)
   Stop
   ' will yield 5 entries

   ' however this senario will yield 6 entries
   s = "1,2,3,4,5, "
   parts = s.Split(New Char() {","c}, StringSplitOptions.RemoveEmptyEntries)
   Stop
TnTinMN 418 Practically a Master Poster

See if this works for your needs:

Private Function WeeksNumFromBasis(ByVal basis As DateTime, ByVal SubjectDate As DateTime) As Double
   Return SubjectDate.Subtract(basis).TotalDays / 7
End Function
TnTinMN 418 Practically a Master Poster

I glad that you have it working. :))

First, regarding the timespan. From the result that i get, total sum that is more than 24 hours will be converted to 1 day, for example: 1.03:04:49.
How can I change the day to 24 hours like 1.03:04:49 will become 27:04:49. Is it possible to do like that?

Yes. There are two ways that I know of to do this. Here is the simplest one.

   Private Sub Chart1_FormatNumber(ByVal sender As Object, ByVal e As System.Windows.Forms.DataVisualization.Charting.FormatNumberEventArgs) Handles Chart1.FormatNumber

      If sender Is Chart1.ChartAreas("Fred").AxisY OrElse TypeOf sender Is System.Windows.Forms.DataVisualization.Charting.DataPoint _
         AndAlso e.ValueType = ChartValueType.DateTime Then
         ' recreate original TimeSpan
         ' Remember that the Chart control uses OADates
         Dim ts As TimeSpan = DateTime.FromOADate(e.Value).Subtract(myToday)
         e.LocalizedValue = Trim(String.Format("{0,4:##00}:{1,2:00}:{2,2:00}", _
                                          (ts.Days * 24) + ts.Hours, _
                                          ts.Minutes, _
                                          ts.Seconds) _
                                 )

      End If

   End Sub

Second, how can i set the Y-Axis to become larger so that the total hour can see clearly

First off, you could make the size of the control taller. There are several values you can set regarding the interval to display less info if that is what you mean. Here is an extend section of what I showed earlier. Its best to play with these and see if you like the results. Normally, I would recommend looking at the documentation, but is this case that is an almost useless activity.

   ' Setup the chart

   With Chart1
      '.Dock = DockStyle.Fill
      .DataSource = dt
      .Legends.Clear() …
TnTinMN 418 Practically a Master Poster

Hi lulu:

The following example is for a WinForm, but I believe the charting control works the same for the a Web app.

You need to first convert the Timespan to a datetime value to chart it, but I guess you already discovered that. ;)

The problem then becomes one of formatting the Y-axis. Not too hard, but it can be confusing. Give this a try on a new WinForm project to which you have added a single chart control to the form.

Imports System.Windows.Forms.DataVisualization.Charting
Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

   ' Make some data
   Dim dt As New DataTable
   Dim r As DataRow
   With dt
      .Columns.Add("Label", GetType(String))
      .Columns.Add("TS", GetType(TimeSpan))
      r = .NewRow : r(0) = "A1" : r(1) = TimeSpan.Parse("0.00:45:00") : .Rows.Add(r)
      r = .NewRow : r(0) = "A2" : r(1) = TimeSpan.Parse("1.01:00:00") : .Rows.Add(r)
      r = .NewRow : r(0) = "A3" : r(1) = TimeSpan.Parse("0.06:00:00") : .Rows.Add(r)
      r = .NewRow : r(0) = "A4" : r(1) = TimeSpan.Parse("0.12:45:00") : .Rows.Add(r)

   End With

   ' Add a DateTime Column
   dt.Columns.Add("ChartTime", GetType(DateTime))


   ' Now for the real work!

   ' I use "Today" as the base date.  In a perfect world we could do:
      'For Each r In dt.Rows
      '   r("ChartTIME") = New DateTime(CType(r("TS"), TimeSpan).Ticks)
      'Next
   ' but the chart control uses OLE Automation dates and they use a 
   ' different time basis than .Net Dates.

   ' set a temp Today to prevent the unlikely case the the day changes while executing …
TnTinMN 418 Practically a Master Poster
TnTinMN 418 Practically a Master Poster

thank you sir but is there any other solutions? beside your suggestions?

What is it that you find unacceptable about the solutions proposed thus far?

TnTinMN 418 Practically a Master Poster

You have discovered the problem in casting (Narrowing conversion) an inheritor class back to it's ancestor class; you loose the added functionality defined in the decendent class. i.e you lost the Add overrides, and the AddWithValue method.

This in itself is not a big problem. You just need to construct a completed parameter of the type you want and add it to the System.Data.Common.DbParametersCollection.

      If applicType = "AccessDatabase" Then
         cmd.Parameters.Add(New OleDb.OleDbParameter("Name", "Fred"))
      Else
         cmd.Parameters.Add(New SqlClient.SqlParameter("Name", "Fred"))
      End If

This should work, but I would like to suggest a different solution to your issue; Instead of using SqlClient, use the "Microsoft OLE DB Provider for SQL Server" (Provider=SQLOLEDB). This way all you would need to do is set the appropriate connection string.

Just remember to use question marks (?) for the substituted parameters in the command text string. I.E.: `cmd.CommandText = "Select * From Labor Where Emp_Name=?"

TnTinMN 418 Practically a Master Poster

You are trying to open a SQL Server Compact db file using the SqlClient provider. You need to be using the methods in the System.Data.SqlServerCe namespace.

See: http://msdn.microsoft.com/en-US/library/system.data.sqlserverce.sqlcedatareader(v=VS.80).aspx for an example

TnTinMN 418 Practically a Master Poster

Both OleDb and Sqlclient classes inherit from base classes in System.Data.Common, so you can assign the specific type to the parent type.

This quick test worked fine for me.

   Dim applicType As String = "AccessDatabase"

   'I just intitialized the objects to get rid of the annoying IDE messages
   Dim conn As System.Data.Common.DbConnection = New SqlClient.SqlConnection
   Dim cmd As System.Data.Common.DbCommand = New SqlClient.SqlCommand
   Dim rdr As System.Data.Common.DbDataReader


   Select Case applicType
      Case "AccessDatabase"
         conn = New OleDb.OleDbConnection()
         cmd = New OleDb.OleDbCommand
      Case "SQLClientDatabase"
         conn = New SqlClient.SqlConnection
         cmd = New SqlClient.SqlCommand
   End Select

   Debug.WriteLine(conn.GetType.FullName)

   conn.ConnectionString = My.Settings.PlayConnectionString
   conn.Open()
   cmd.Connection = conn
   cmd.CommandText = "Select * From Labor"
   rdr = cmd.ExecuteReader
   While rdr.Read
      'do your stuff
      'Stop
   End While
   conn.Close()
TnTinMN 418 Practically a Master Poster

You are attempting to use the SQLDataReader class, did it occur to you to to look at the documentation.
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader%28v=vs.100%29.aspx
It gives a basic example of how to implement it.

TnTinMN 418 Practically a Master Poster

Logic Error

If PathRead() = 0 Then
            MsgBox("Error Reading Path Info: One or more Paths do not exist.", MsgBoxStyle.Critical, "Path Read Error")
            MsgBox("Would you like to create these files?", MsgBoxStyle.YesNo, "Create?")
            If MsgBoxResult.Yes Then
                MkDir("/Paths/")
                System.IO.File.Create("/Paths/aPath.txt")
                System.IO.File.Create("/Paths/mPath.txt")
                System.IO.File.Create("/Paths/lPath.txt")
                System.IO.File.Create("/Paths/wPath.txt")
            End If
End If

Should be:

If PathRead() = 0 Then
            MsgBox("Error Reading Path Info: One or more Paths do not exist.", MsgBoxStyle.Critical, "Path Read Error")

            If MsgBox("Error Reading Path Info: One or more Paths do not exist." & vbcrlf & _
                      "Would you like to create these files?", MsgBoxStyle.YesNo, "Create?") = MsgBoxResult.Yes Then
                MkDir("/Paths/")
                System.IO.File.Create("/Paths/aPath.txt")
                System.IO.File.Create("/Paths/mPath.txt")
                System.IO.File.Create("/Paths/lPath.txt")
                System.IO.File.Create("/Paths/wPath.txt")
            End If
End If
TnTinMN 418 Practically a Master Poster

Ok, let's walk this through.

If RadioButton0 is clicked, it's "Checked" property will be True. Every time this happens you run the "clear" method. You also want the to execute the "clear" method by clicking ButClr that is parented by the "Calculator" class. It appears that your reference to the "CourseTab" class is named "courseTab". "clear" is defined as a Public method which means it can be called in ButClr_Clicked by adding the following statement to the "ButClr_Clicked" method:

`courseTab.clear`

The only thing that calling the method like this will not accomplish is setting RadioButton0's "Checked" state to True. Since you have not shown that you are handling the RadioButton0.CheckChanged event, there appears to be no reason that setting this in the "clear" method would be a problem. So you could add the follow statement to the "clear" method.

RadioButton0.Checked = True

With that stated, I will not try anymore to steer you way from the programming practice of programmatically clicking buttons.

InvokeOnClick is a protected method, meaning that sans using Reflection, you can only invoke it in the inherited class in which the statement resides. You are trying call it as a public method. It won't work.

You could do something like this though:

Me.InvokeOnClick(courseTab.RadioButton0, New EventArgs)

Take note that this will only work if RadioButton0 is declared Public or if it is delcared Friend and the declaration resides in the same assembly from which it is being accessed.

TnTinMN 418 Practically a Master Poster

So you are maintaining two lists; one for the words and the second to to strore the number of occurence of that word.

Why not use the dictionary class as was previously suggested by ddanbe?
It has all the functionallity you require already built-in.

private Dictionary<string, Int32> words = new Dictionary<string, Int32>();

Then you could do something like this:

      string subjectword = "fred";  // the current word you are working with

      if (words.ContainsKey(subjectword))
      {
         words[subjectword] += 1;
      }
      else
      {
         words.Add(subjectword, 1);
      }
TnTinMN 418 Practically a Master Poster

I think this:

cmd.CommandText = "select last_name, first_name, middle_name from tenant where last_name = '" & Me.ComboBox1.Text & "' AND first_name = '" & Me.ComboBox2.Text & " AND middle_name" & Me.ComboBox3.Text & "'"

should be

cmd.CommandText = "select last_name, first_name, middle_name from tenant where last_name = '" & Me.ComboBox1.Text & "' AND first_name = '" & Me.ComboBox2.Text & "' AND middle_name='" & Me.ComboBox3.Text & "'"
TnTinMN 418 Practically a Master Poster

So that is what they teach! Augh!!!!!!!!!!!!!!

If you have a block of code that needs to be called by multiple event handlers, it is best to define that code block as a separate method (subroutine) and call it as needed.

Something like this pattern.

Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton1.CheckedChanged
   If RadioButton1.Checked Then DoSomething()
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
   DoSomething()
End Sub

Sub DoSomething()
   'well, I would do something if I knew what to do.
End Sub

To programmaticallly click a button, you could do this:

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
   Button1.PerformClick()
   RadioButton1.PerformClick()
End Sub

But if you really want to use Control.InvokeOnClick:

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
   Me.InvokeOnClick(Button2, New EventArgs)
End Sub

This assumes that "Me" is a class that has the Control class somewhere in it's inheritance tree.

TnTinMN 418 Practically a Master Poster

It would help if you showed your code. Also would help if you identified the line of code that throws the error.

TnTinMN 418 Practically a Master Poster

How was the photo saved to Access?

Was it written as a BLOB by a program you wrote or was is it added In MS Access 2007 or newer as an attachment?

TnTinMN 418 Practically a Master Poster

Performing computions on TimeSpan and DateTime types are two areas that the DataTable class does not support very well.

That said, you are left to process the rows yourself in code.

Here are two options, both of which entail creating an array of resultant rows that can then be added to a new DataTable

  1. You could iterate through the table and create a list of unique LINENAME's and then do a DT.Rows.Select to pull those rows. You would then need to iterate through the returned rows and perform the summation. Then this result would be converted into a new DataRow and stored in an Array of DataRows.

    Not difficult to do and it is easy to follow the code logic.

  2. The second option essentially does the above, but uses a LINQ query on the DataTable to group and compute. These can be compact statements, but are confusing to those who do not use them very often. This will return an IENumerable(Of DataRow) that can then be iterated through and added to a DataTable.

I am going to show the LINQ method.

For your particular problem, we need to deal with the TimeSpan structure. To get a value that can be summed, I use the "Ticks" property and sum that value.

The method shown below handles the conversion the string TimeSpan value directly. No need for the TimeSpan conversion sterp that you showed.

As I do not do webpages, I have written and tested this in a WinForm project. You …

TnTinMN 418 Practically a Master Poster

You are adding parameters that may not exist in the command string.

INSERT INTO [Customer] (Company, Business_Phone, Home_Phone, Mobile_Phone, Fax) VALUES (@CMPNY, @BUSPH, @HOMPH, @MBLPH, @FAXNM)
In this case you will have parameters for Last_Name and First_Name that are empty. I believe that the parameters must be in the order requested as it doe not do a look-up of the provided parameters.

I have restructured your code and eliminated some unnecessary functional but confusing code.

   Dim custstr As String = "INSERT INTO [Customer] ("
   Dim valuestr As String = ") VALUES ("

   Dim custcmd As New OleDbCommand()
   Dim txt As String
   txt = txt_company.Text

   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length <> 0 Then
       custstr &= "Company"
       valuestr &= "@CMPNY"
       custcmd.Parameters.AddWithValue("@CMPNY", txt_company.Text)
   End If

   txt = txt_lastname.Text
   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length <> 0 Then
       custstr &= ", Last_Name"
       valuestr &= ", @LSTNM"
       custcmd.Parameters.AddWithValue("@LSTNM", txt_lastname.Text)
   End If

   txt = txt_firstname.Text
   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length <> 0 Then
       custstr &= ", First_Name"
       valuestr &= ", @FSTNM"
       custcmd.Parameters.AddWithValue("@FSTNM", txt_firstname.Text)
   End If

   txt = txt_busphone.Text
   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length <> 0 Then
       custstr &= ", Business_Phone"
       valuestr &= ", @BUSPH"
       custcmd.Parameters.AddWithValue("@BUSPH", txt_busphone.Text)
   End If

   txt = txt_homephone.Text
   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length <> 0 Then
       custstr &= ", Home_Phone"
       valuestr &= ", @HOMPH"
       custcmd.Parameters.AddWithValue("@HOMPH", txt_homephone.Text)
   End If

   txt = txt_mobilephone.Text
   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length <> 0 Then
       custstr &= ", Mobile_Phone"
       valuestr &= ", @MBLPH"
       custcmd.Parameters.AddWithValue("@MBLPH", txt_mobilephone.Text)
   End If

   txt = txt_fax.Text
   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length …
TnTinMN 418 Practically a Master Poster

the time format is 00:00:00 0 is time(7), i will try TnTinMN method , and i will see what will be going.

The SQL Time datatype will through a wrench in the machinery for using the datatable expression. This datatype gets converted to a .Net TimeSpan and there is no way that I know of to achieve the data manipulations necessary to get this to a decimal value need to compute "Cost" in a datacolumn expression. You can follow the example I provided up to the point of adding the expression statement with this minor change to the Select statement in the query.

SELECT Empl_Name, Hours_Worked, Rate, CAST(CAST(Hours_Worked AS DateTime) AS Float) * 24.0 * CAST(Rate AS Float) AS Cost FROM Labor

In the case where you would be using the DGV for entry/editting, it will be necessary to handle the CellValueChanged event. Here is an example for that.

   Private Sub LaborDataGridView_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles LaborDataGridView.CellValueChanged
      If Not LaborDataGridView.IsHandleCreated Then Exit Sub 'handles initialization

      If LaborDataGridView.Columns(e.ColumnIndex).DataPropertyName = "Hours_Worked" OrElse _
         LaborDataGridView.Columns(e.ColumnIndex).DataPropertyName = "Rate" Then
         'get the underlying datatable row
         Dim dr As DataRow = CType(LaborDataGridView.Rows(e.RowIndex).DataBoundItem, DataRowView).Row
         'set cost to reflect changes
         dr("Cost") = CType(dr("Hours_Worked"), TimeSpan).TotalHours * CType(dr("Rate"), Decimal)
         LaborDataGridView.InvalidateRow(e.RowIndex) 'refresh the row with new value
      End If

   End Sub
TnTinMN 418 Practically a Master Poster

IsDigit code will allow to enter everything apart from digits....

So put "Not" in front of it. If Not Char.IsDigit(e.KeyChar) Then

The "Char.XXx" functions will account for regional language settings that use unicode characters outside the range of those used for English letters.

TnTinMN 418 Practically a Master Poster
TnTinMN 418 Practically a Master Poster
TnTinMN 418 Practically a Master Poster

You may want to review this article.
http://www.codeproject.com/Articles/3467/Arrays-UNDOCUMENTED

I also remebered reading somewhere that the outermost dimension should be iterated before the inner ones. If I recall correctly, it has something to do with the layout in memory, but don't quote me on that.

I ran a test case of your original versus flipping the iteration sequence and it made a big improvement. I also tried using jagged arrays as mentioned in the article.

On my test system Vista32, VS2008, the jagged array (modified iterator sequnce) had the best performance. Approx 35% of original time.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

        public Form1()
        {
            InitializeComponent();

            if (System.Diagnostics.Stopwatch.IsHighResolution)
            {
                Console.WriteLine("Operations timed using the system's high-resolution performance counter.");
            }
            else
            {
                Console.WriteLine("Operations timed using the DateTime class.");
            }

        }

        int iterations = 100;

        private void button1_Click(object sender, EventArgs e)
        { // original
            button1.Enabled = false;
            GC.Collect(); // just for performance testing
            sw.Reset();
            sw.Start();

            double[,] Redmap = new double[640, 480];
            double[,] Greenmap = new double[640, 480];
            double[,] Bluemap = new double[640, 480];


            double[,] Redmap2 = new double[640, 480];
            double[,] Greenmap2 = new double[640, 480];
            double[,] Bluemap2 = new double[640, 480];


            for (int i = 0; i < iterations; i++)
            {
                for (int y = 0; y < 480; y++)
                {

                    for (int x = 0; x < 640; x++)
                    {
                        Redmap2[x, y] = Redmap[x, y] * 2;
                        Greenmap2[x, y] = Greenmap[x, y] …
TnTinMN 418 Practically a Master Poster

Hiba,

No offense intended, but the DataGridView control is really intended as a viewer for data in a tabular format and not as a spreadsheet. It would be better to handle these calculations in the backing data storage. Even if the data is not pulled from a database, it is much easier to create a datatable with a computed column and set the DGV's datasource to your created table.

Let's assume you are using a database for that you have created a dataset for through the designer. We will edit the datasource. This is just a simple Access DB that I created, but the type of database is irrelevant.

0

148
Now we are going to add a new column to hold the result of multiplying "Hours_Worked" by "Rate". We will name this column "Cost".
229
Go to the properties for "Cost" and set its DataType to decimal.

313
Ok, now we have cost column in the dataset, however it does not exist in the database. We will create it in our fill query.
45
Click the "Next" button until you reach the Sql screen.
52
We will edit the "Select" statement to add the "Cost" column
Hours_Worked * Rate As Cost
65

Click "Next" and give a name for the two methods.
71

Reverend Jim commented: Great post. Should be a tutorial. +11
TnTinMN 418 Practically a Master Poster

I suspect that you are getting a cross-thread error that is causing the routine to fail. Are trying to acces the datagridview in the background worker? If so, that is likely the cause.

TnTinMN 418 Practically a Master Poster

Have you installed Service Pack 1? The base install has a lot of issues corrected by the service pack.

http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=13276

TnTinMN 418 Practically a Master Poster

The richtextbox uses chr(10) (VBLf) to designate a new line. So if that is working, then check for VBLf (this is a VB character constant).

On non-Unix systems, the System.Environment.NewLine is a two character string equivalent to chr(13) & chr(10). You could also use the VB constant VBCrLf for this.

What is it that you are trying to accomplish? There are most likely other methods that could be suggested.

TnTinMN 418 Practically a Master Poster

I am going to assume that you mean adding a video to the embedded resources.

From the menu, goto Project->Properties. Then select the "Resources" tab. Next Select "Add Rersource"->"From Existing File". You can then select your video file. The file will be inserted with the File Name minus the extension as a binary array.

As far as I know, the media player control can only except a file reference to play. Therefore, you will need to write the binary array to a temporary file first.

Private TmpFiles As New List(Of String)

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
   Dim fi As New IO.FileInfo(IO.Path.GetTempFileName())

   Dim tmppath As String = IO.Path.GetTempFileName()
   ' The tmp file will have a ".tmp" extension
   ' The media player uses the extension to identify the proper codec to use to decode the file
   ' I used a wma video, so I will change the extension to that
   tmppath = tmppath.Replace(".tmp", ".wma")
   ' Create the file and write the resource array to it
   Dim tmp As IO.Stream = IO.File.Create(tmppath)
   ' Amanda is the name of my file
   tmp.Write(My.Resources.Amanda, 0, My.Resources.Amanda.Length)
   tmp.Close()

   'Save a reference to tmp file so that you can delete it on the Form.Closing event
   TmpFiles.Add(tmppath)

   ' tell the player to play the file
   WMP1.currentMedia = WMP1.newMedia(tmppath)

End Sub


Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
   For Each file As String In TmpFiles
      Try
         IO.File.Delete(file)
      Catch ex As Exception
         ''
      End Try
   Next
End Sub …
TnTinMN 418 Practically a Master Poster

Sorry, I did not take the time to try and understand your goals the first time. I think this example should get you going.

Public Class Form1

   ' Assuming you want to add 10 textboxes
   ' By declaring this reference at the Form level you can directly access the TB by index

   Private AddedTBs(0 To 9) As TextBox

   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

      Dim startY As Int32 = 10 'Starting vertical position

      For i As Int32 = 0 To UBound(AddedTBs)
         AddedTBs(i) = New TextBox
         With AddedTBs(i)
            ' setting the Name will allow you to identify the TB later
            ' in the Form's control collection
            .Name = "AddedTB" & (i + 1).ToString 'start with AddedTB1
            .Size = New Size(100, 20)
            ' set vertical position based on even spacing of the controls height
            ' plus 5 pixels between the controls
            .Location = New Point(10, If(i = 0, startY, startY + ((.Size.Height + 5) * i)))
            .Parent = Me
            ' If you need to handle events for the TB's, you need to wire-up
            ' the handler yourself

            ' assume you want to handle the textchanged event for this TB
            AddHandler .TextChanged, AddressOf AddedTBs_TextChange

            ' assume you want to handle the textchanged event for this TB
            AddHandler .KeyPress, AddressOf AddedTBs_KeyPress

         End With
      Next
   End Sub

   Private Sub AddedTBs_TextChange(ByVal sender As Object, ByVal e As System.EventArgs)
      'get a reference to the TB whose text is changing
      Dim tb As TextBox = CType(sender, TextBox)
      'some code
   End Sub …
TnTinMN 418 Practically a Master Poster

kRod,

First off, GREAT JOB!!!!!

Two minor things in your code.

  1. You declare and set "maxSize", but it is never used in your logic. Just delete all references to it.

  2. You use GetNextControl. This is a tricky function to use and I wish MS would reroute people to SelectNextControl as that is what most people really want anyways.

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.selectnextcontrol.aspx

Your code is fine as is, but I took the liberty to convert it to a custom control for you and to show a different style of handling the keypress event. This will also show you how to use the SelectNextControl function. Just add this class to your project and rebuild it. If you have the default settings for Visual Studio, you should see it show up in your toolbox.

Public Class kRodsTB
   Inherits System.Windows.Forms.TextBox

   Public Sub New()
      Me.MaxLength = 10
   End Sub

   Public Shadows Property MaxLength() As Int32
      Get
         Return MyBase.MaxLength
      End Get
      Set(ByVal value As Int32)
         If value = 4 OrElse value = 10 Then
            MyBase.MaxLength = value
         Else
            Throw New ArgumentException("MaxLength must be either 4 or 10")
         End If
      End Set
   End Property

   Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)
      ' The "Select Case" block processes the conditions in the order written
      ' and allows (IMO) easier reading and segmentation of the conditional logic

      Select Case e.KeyChar
         Case Chr(Keys.Enter)
            'If only a decimal point is in the box clear TextBox
            If Me.TextLength = 1 And (Me.Text = "." Or Me.Text = "-") Then Me.Clear() …
kRod commented: Nice Work on the Control +2
TnTinMN 418 Practically a Master Poster

Dim txtBx() As New TextBox

TnTinMN 418 Practically a Master Poster
Class MainWindow 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
        Dim Other As New Window1(TextBox1)
        Other.Show()
    End Sub
End Class

Public Class Window1
   Private DestTB As TextBox
   Public Sub New(ByVal DestTB As TextBox)
      InitializeComponent()
      Me.DestTB = sourceTB
   End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
        Me.DestTB.Text = TextBox1.Text
    End Sub
End Class
TnTinMN 418 Practically a Master Poster

At the top of your code type this:

Option Strict On

Better yet, on the menu got Tools->Options. Expand the "Projects and Solutions" node. Select "VB Defaults" and turn it on there.

This will allow Visual Studio to point you to many mistakes in your code.

Look at this line:
if .ds.Tables("a").Rows.Count= "Administrator" Then
What does:.ds.Tables("a").Rows.Count return? (Hint: an integer value)
Will an integer value ever be equal to the string "Administrator"?

TnTinMN 418 Practically a Master Poster

The ommision of ByVal is a non-optional "feature" MS added in VB2010 SP1. ByVal is the default parameter passage mechanism in .Net. Supposedly MS originally used the placement of ByVal as a reminder for those migrating from VB6 where ByRef is default.

TnTinMN 418 Practically a Master Poster

How did you add the files? Are they in an external assembly?

If you added them via Project-.Properties and the "Resources" tab and you know the name, there is no need to enumerate through the entries. You can just access using "My.Resources.NameYouWant".

TnTinMN 418 Practically a Master Poster
TnTinMN 418 Practically a Master Poster

Now when I type something in textbox1 and lose focus, textbox2 is altered but when I click the button neither textbox is updated.

Obviously if I uncomment the call to notifyPropertyChanged all works fine. This however brings up questions in my mind.

  1. If I change textfield1 this must be changing the datasource and then the datasource somehow triggers textbox2 to re-fetch the data then displaying it.

The default datasource update mode is . When you leave the textbox you trigger its validation. If you set the TextBox.CauseValidation property to false, you would not see the second textbox update to reflect the change to the datasource.

If you use the longer Add method overload and specify "OnPropertyChanged" for the update mode, you will see the other textbox change as you type. "OnValidation" and "OnPropertyChanged" are for the control and its property to which you are adding the binding, not the datasource.

I'm not sure about this but it makes sense to me. If one databound control fires an event to update the datasource, then the binding manager does not require the property change event from the datasource (as it is the source of the change) to know that it needs to update all other controls bound to the same datasource.

  1. If I click the button this changes the datasource but for some reason the control isn't triggered to fetch the data again.

As you have disabled the property change notification, the binding manager has no way to …

TnTinMN 418 Practically a Master Poster

Just food for thought, but why not impliment the API function CopyFileEx? http://msdn.microsoft.com/en-us/library/windows/desktop/aa363852%28v=vs.85%29.aspx

PInvoke.Net has an example. http://www.pinvoke.net/default.aspx/kernel32/CopyFileEx.html

This function gives you the relative safety of using a standard Windows library function along with the file progress reporting capability that you want.

TnTinMN 418 Practically a Master Poster

I recommend that you create a BindingNavigator to manage navigation.
Your current implimentation has no error checking and the navigator will do all that for you.
http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingnavigator(v=vs.90).aspx

With a navigator you can define the buttons that handle navigation. The one draw back is that they need to be ToolStrip items. Add an undocked toolstrip for each button that you want to have in your form and set the autosize property to false; also set the LayoutStyle to Table. To replace your current buttons, add a Toolstipbutton to the toolstrip and make it look like your original button. You can also add buttons for goto first and goto end. To allow jumping to a specific row (PositionItem), add a toolstriptextbox. To get a total of the row, add another toolstriptextbox for CountItem and make it read-only.

If you do this and modify your code as follows, you can delete all your existing button-click code and your "gridvalues" method code.

On an issue of readability, I suggest that you name the buttons and textboxes to reflect what they actually display on the form.

Private MyNavigator as New BindingNavigator(False)

Private Sub Telefon_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    OleDbDataAdapter1.Fill(DatasetTelefonija1)
    DataGridView1.Columns(0).HeaderText = "Redni broj"
    DataGridView1.Columns(1).HeaderText = "Ime i prezime"
    DataGridView1.Columns(2).HeaderText = "Telefon"
    DataGridView1.Columns(3).HeaderText = "Ostalo"


    With MyNavigator
       .Parent = Me
       .BindingSource = Me.TelefoniBindingSource
       .PositionItem = ToolStripTextBox1
       .CountItem = ToolStripTextBox2
       .MovePreviousItem = ToolStripButton1
       .MoveNextItem = ToolStripButton2
       .AddNewItem = ToolStripButton3
       .DeleteItem = ToolStripButton4
       .MoveFirstItem = ToolStripButton5
       .MoveLastItem = …
TnTinMN 418 Practically a Master Poster

I am forced to conclude by the syntax "getcomments()" that getcomments is a function that returns an ArrayList. Howerver without seeing that function it is not possible offer any insite as to why this is happening.

TnTinMN 418 Practically a Master Poster

Here is what the source will look like:
text1 = text1
text2 = text2
text3 = text3
text4 = text4
text5 = abcdefg (Yes)
text6 = hijklmn (Yes)
text7 = 1234567 (No)
text8 = abcdefg (No)

What I want to pull is any data that is marked Yes, so in this case abcdefg and hijklmn.

   'get all lines in the text file
   Dim text() As String = System.IO.File.ReadAllLines("sample.txt")

   'create an array of only those lines that contain "(Yes)"
   Dim YesLines() As String = Array.FindAll(text, Function(str As String) str.Contains("Yes")).ToArray
   ' or
   'Dim YesLines() As String = text.Where(Function(str As String) str.Contains("Yes")).ToArray


   'Process the lines to remove unwanted text (Text# = ) and (Yes)
   '1st cut-off "Text# =" using SubString
   'then replace (Yes) with nothing
   'finally trim leading and trailing spaces
   Dim WantedText() As String = YesLines.Select( _
                                   Function(str As String) _
                                   str.Substring(str.IndexOf("=") + 1).Replace("(Yes)", "").Trim _
                                               ).ToArray()

   'You now have the data you want in a string array
   'If you need this array as a single string
   Dim oneline As String = String.Concat(WantedText)
TnTinMN 418 Practically a Master Poster

Just thought about the decimal seperator.

   Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
      If (Not Char.IsLetterOrDigit(e.KeyChar)) And e.KeyChar <> Threading.Thread.CurrentThread.CurrentUICulture.NumberFormat.NumberDecimalSeparator Then
         e.Handled = True
      End If
   End Sub
TnTinMN 418 Practically a Master Poster

You lost me on your sequence of events. However, the simplest way to store the textbox is to use "UserSettings". Go to Project->Properties and select the Settings tab. Create three setting like these:

Then in your notepad form do something like this:

   Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
      My.Settings.SavedTBText = TextBox1.Text
      My.Settings.SavedTBSelectionStart = TextBox1.SelectionStart
      My.Settings.SavedTBSelectionLength = TextBox1.SelectionLength
   End Sub

   Private Sub Form_NotePad_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
      With TextBox1
         .Text = My.Settings.SavedTBText
         .SelectionStart = My.Settings.SavedTBSelectionStart
         .SelectionLength = My.Settings.SavedTBSelectionLength
      End With
   End Sub

This will save/restore the state of the textbox on the notepad form.