|
If the designer creates a progressbar it does this
Me.ProgressBar1 = New System.Windows.Forms.ProgressBar
and a bit further down
'ProgressBar1
'
Me.ProgressBar1.Location = New System.Drawing.Point(630, 181)
Me.ProgressBar1.Name = "ProgressBar1"
Me.ProgressBar1.Size = New System.Drawing.Size(453, 23)
Me.ProgressBar1.Step = 1
Me.ProgressBar1.Style = System.Windows.Forms.ProgressBarStyle.Marquee
Me.ProgressBar1.TabIndex = 54
If I want to increment the progressbar at runtime I just do this
Progressbar1.Value = Progressbar1.Value + 1
Is the word Progressbar1 that is used to access the .value assigned by the .name or is it from the Me.ProgressBar1 = New System.Windows.Forms.ProgressBar assignment?
I have created some controls that include progress bars that are created at runtime by going through a dataset. Each record has a name field and I create a progress bar for every record using the record name as the progressbars.name property
This is some of my code:
Dim progName(RobotRecordsCount) As ProgressBar
Dim myLoop as integer
For myLoop = 0 To (RobotRecordsCount - 1)
currentName = (Mafia_Wars_ManagerDataSet.Robots(myLoop).Name)
'Create a progressbar
progName(myLoop) = New ProgressBar()
progName(myLoop).Location = New Drawing.Point(ProgBarPosVer, lblposHoz) 'lblposVer, ProgBarPosHoz)
progName(myLoop).Name = "Prog" + currentName
progName(myLoop).Width = 300
progName(myLoop).Height = 20
progName(myLoop).Minimum = 0
progName(myLoop).Maximum = 30
TabControl1.TabPages(0).Controls.Add(progName(myLoop))
How do I then do the equiv of
progName???.Value = progName???.Value + 1
1. I am confused how to update it after it has been created
2. As it is created at runtime how will intellisense know it exists without complaining (is this called late binding)?
I know that this is probably a fundamentals question so i'm sorry if it bugs you trying to run before i can walk. I am obviously lacking in foundation so I have ordered some books to rectify this.
Again thankyou for your previous response. I have been working and learning for 3 weeks without reulting to asking questions but I seem to have hit a wall.
|
|
|
|
|
the normal way to refer an object is by a reference, which you keep in a variable.
dim P as ProgressBar = new ProgressBar()
is what makes
P.Value = 42
possible. But "P" is NOT the name of the progress bar. It is the name of the variable that you can use to refer to the progress bar. And there is no Name property involved.
dim P as ProgressBar = new ProgressBar()
dim Q as ProgressBar = P
P.Value = 42
Q.Value = 13
uses two variables to refer to one and only one progress bar, which ends with a value of 13.
As such, the progressbar *has* no name, the variable(s) referring to it have a name.
On top of that, Controls have a Name property, which is not directly useful, however it is where Visual Designer stores the name of the variable it creates to hold the reference to that Control, so it can later on generate more code for that Control.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that. [The QA section does it automatically now, I hope we soon get it on regular forums as well]
|
|
|
|
|
I assume that what you want is to refer to the ProgressBar by the name field.
There are a couple of ways that you can do that. One way that I see is to use a Hashtable . Declare it globally like
Public myProgressBars as Hashtable
Then, when you set up each ProgressBar add a line of code to add that ProgressBar to the Hashtable like
myProgressbars.Add(currentName, New ProgressBar())
Instead of what you have, it could look like
Dim myProgressBars As Hashtable
Dim myLoop as integer
For myLoop = 0 To (RobotRecordsCount - 1)
currentName = (Mafia_Wars_ManagerDataSet.Robots(myLoop).Name)
myProgressBars.Add(currentName,New ProgressBar())
With CType(myProgressBars(currentName), ProgressBar)
.Location = New Drawing.Point(ProgBarPosVer, lblposHoz)
.Name = "Prog" + currentName
.Width = 300
.Height = 20
.Minimum = 0
.Maximum = 30
End With
TabControl1.TabPages(0).Controls.Add(CType(myProgressBars(currentName),ProgressBar))
Then, whenever you want to update that ProgressBar you just call
CType(myProgressbars(progName),ProgressBar).Value = x
|
|
|
|
|
You could use a generic Dictionary rather than a Hashtable because a Dictionary can be typed, which avoids the need for the ugly CType when you read it back again:
Dim myProgressBars as New Dictionary(Of String, ProgressBar)
...
With myProgressBars(aName)
...
myProgressBars(aName).value = x
|
|
|
|
|
Hi,
I'm using a simple method to validate XML against an XSD. Here's how it looks:
Private Sub ValidateXML(ByVal xml As String)
Dim settings As New XmlReaderSettings()
settings.ValidationType = ValidationType.Schema
settings.Schemas.Add("", "c:\apps\srg\uhc\interfaces\web\services\xsd\DirectCallToASE.xsd")
AddHandler settings.ValidationEventHandler, AddressOf OnValidationError
Dim reader As XmlReader = XmlReader.Create(xml)
Try
While reader.Read()
End While
Catch ex As Exception
End Try
reader.Close()
End Sub
I get a run time error here:
settings.Schemas.Add("", "c:\apps\srg\uhc\interfaces\web\services\xsd\DirectCallToASE.xsd")
System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.ArgumentException: Illegal characters in path.
I tried just "DirectCallToASE.xsd" and that returned File Not Found. I also tried Server.MapPath("xsd/DirectCallToASE.xsd") and that also returned Illegal characters in path.
It's a valid path.... I'm not sure what it doesn't like. Any ideas?
Thanks!
|
|
|
|
|
Oops! I just looked at my stack trace a little more closely, and I see that the actual error is here:
Dim reader As XmlReader = XmlReader.Create(xml)
On XmlReader.Create, Overload 4 will accept the parameter as System.IO.Stream. I take it a string of XML won't work? How would I convert a string to a stream, and them use it create the XML reader.
Or better yet, this is what I am really trying to do: Validate an object against an XSD. There never is an XML file, just an memory resident object. Is there a better way to approach this?
Thanks!
|
|
|
|
|
Hi there.
Sorry if this is long winded. I am relatively new to programming and have managed so far with google and a lot of patience! I am having a problem naming timer contols at runtime. This is what I am trying to achieve.
1. I connect to my dataset and to my first record
2. I create a loop for the recordset
3. I create various objects on a form and name them using the info in the dataset
I also need to create timers and name them using the first field of my dataset. It needs to be dynamic as its database driven. There could be as many as 100 timers at any one point.
I can use the Button.name = "myname" fine for most controls
but doing a Timer.name does not work
This is some of my code (some variable values not shown):
'Counter to move through the database Dataset
Dim RecordsCount As Integer
RecordsCount = ManagerDataSet.Robots.Count
'Declare name incremented with record number to make it unique
Dim btnSSName(RecordsCount) As Button
For myLoop = 0 To (RecordsCount - 1)
'Create a button
btnSSName(myLoop) = New Button()
btnSSName(myLoop).Location = New Drawing.Point(btnSSPosVer, lblposHoz) 'lblposVer, ProgBarPosHoz)
btnSSName(myLoop).Name = "btnSS" + currentRobot
btnSSName(myLoop).Text = currentRobot
btnSSName(myLoop).Width = 70
btnSSName(myLoop).Height = 23
btnSSName(myLoop).BackColor = Color.Red
btnSSName(myLoop).ForeColor = Color.White
TabControl1.TabPages(0).Controls.Add(btnSSName(myLoop))
next myLoop
That all works great for populating objects on the form.
When I create a timer in a similar way:
Dim tmr(RecordsCount) As Timer
tmr(myLoop) = New Timer
tmr(myLoop).Interval = whatevermydatasetrecordis
tmr(myLoop).Name = "myuniquename"
AddHandler tmr(myLoop).Tick, AddressOf hndlifespan
*****The Problem ******
Using . .
tmr(myLoop).Name = "myuniquename"
I get a error of 'Name' is not a member of 'System.Windows.Forms.Timer'
When one of my dynamicly created buttons is pressed it goes to the dynamically created button click handler. This in turn knows which button was pressed by asking its name. At this point I want to launch a specific timer based on the button name.
So if the button "Alpha" was pressed I want to enable the "Alpha" timer (that was created dynamically from the dataset with its associated interval).
I have created a timer at design time which does this:
Friend WithEvents billy As System.Windows.Forms.Timer
Me.billy = New System.Windows.Forms.Timer(Me.components)
If I do the same
Dim billy As Timer
billy = New Timer
The timer is stuck with the name "billy" still and I am unable to change it.
I wish to name the timer with a name that is held in a string. At the moment I acn see that
Dim myString As Timer
can not work as It is an assigned string
so
Dim tmr(CInt(myString)) As Timer
tmr(CInt(myStringt)) = New Timer
AddHandler tmr(CInt(myString)).Tick, AddressOf hndlifespan
does not flag errors in intellisense but I have no idea why it asked me to convert my string into an Integer and if it will work.
I am burned out and lost !!!!!!!!
Many thanks and sorry if I made your head hurt!
Paul
|
|
|
|
|
Take the property field Tag instead of Name. Its designed for user purposes only.
Greetings
Covean
|
|
|
|
|
Hi,
seems you are confused:
- every Control has a Name property
- it gets used by Visual Designer to link back to the variable that will hold the Control's reference
- a Timer is NOT a Control, it is a Component
- Components don't have a Name property
- the Name of a Control does not relate to the name of the variable holding a reference to that Control, unless you set them identically, as Visual Designer does.
So you will need another scheme to achieve whatever it is you are trying to achieve.
And please show properly formatted code, i.e. use PRE tags.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that. [The QA section does it automatically now, I hope we soon get it on regular forums as well]
|
|
|
|
|
When pasting code use the code block for chunks of code or inline code if using it within [Dim xyz ] a sentence. It makes it a whole lot easier to read, and you will more likely get a response.
How many timers are you trying to create?
Are you wanting to change the name just so you can easily reference them dynamically?
|
|
|
|
|
You are getting that error since Timer does not has Name property. If I had do this, I would have gone fro something like this (C# code):
In the Load event (or wherever you want to create a button):
Button btn = new Button();
btn.Name = "SomeName1";
btn.Click += new EventHandler(btn_Click);
Button btn = new Button();
btn.Name = "SomeName2";
btn.Click += new EventHandler(btn_Click);
.
.
.
And so one
Note that all the buttons have same click event. Now, in the click event:
Button btn = sender as Button;
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
timer.Tag = btn.Name;
timer.Tick += new EventHandler(timer_Tick);
Here, you can place a check if that timer has already been created. Now, all the timers will have same tick event. So, in that event,
System.Windows.Forms.Timer timer = sender as System.Windows.Forms.Timer;
switch(timer.Tag.ToString()){
case "buttonName":
break;
}
Using that switch case, you can identify the timer and button pair.
If you can explain why are you doing all this, someone can show up with a better solution than this.
"No matter how many fish in the sea; it will be so empty without me." - From song "Without me" by Eminem
|
|
|
|
|
Hi Paul
If I am getting you correctly, you need to start a specific timer when it's corresponding button is clicked. To be honest I never followed your code, but I would do something like this
Public Class Form1
Private lstButtons As New List(Of Button)
Private lstTimers As New List(Of Timer)
'create array of integers for timer intervals
Private arrIntegers() As Integer = {25, 46, 91, 38, 50}
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For i As Integer = 0 To 4
Dim newButton As New Button
newButton.Name = i
newButton.Text = "Button " & i
newButton.Width = 75
newButton.Height = 25
newButton.Left = 10
newButton.Top = 10 + (25 * i) + (5 * i)
newButton.Parent = Me
newButton.Visible = True
AddHandler newButton.Click, AddressOf ButtonsClick
lstButtons.Add(newButton)
Dim newTimer As New Timer
newTimer.Interval = arrIntegers(i)
AddHandler newTimer.Tick, AddressOf TimersTick
lstTimers.Add(newTimer)
Next
End Sub
Private Sub ButtonsClick(ByVal sender As Object, ByVal e As System.EventArgs)
Dim intIndex As Integer = CInt(CType(sender, Button).Name)
lstTimers(intIndex).Start()
End Sub
Private Sub TimersTick(ByVal sender As Object, ByVal e As System.EventArgs)
CType(sender, Timer).Stop()
MsgBox(CType(sender, Timer).ToString)
End Sub
End Class
I have used lists rather than arrays (personal preference), but the gist of it should be the same. Instead of giving the buttons a name in the form of a string, use a number, and then reference the timer using the button name as an index. Hope this helps
|
|
|
|
|
On top of what everyone else said, you have to be careful creating and disposing the System.Windows.Forms.Timer. Most people do not realize you have to call Dispose on them when you destroy them. Since Timers are not unlimited, you will eventually run the system dry on resources if you constantly create and destory Timers in your app.
|
|
|
|
|
Thank you everyone I really appreciate it.
I took some time out and realised I only need one timer event.
There is still one thing I am struggling with to understand but I put it in a new thread as its a different question.
|
|
|
|
|
Im not quite sure I understand why it is you needed alot of timers, as im sure there would be a better way to do it.
I would have thought that you could just use Threads.
Dim t As New Threading.Thread(AddressOf myThread)
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
t.Start()
End Sub
Private Sub myThread()
Do
'Work to be done
'....
' Waits 5 seconds before next iteration
Threading.Thread.Sleep(New TimeSpan(0, 0, 5))
'Or for miliseconds use this: Threading.Thread.Sleep(500)
Loop
End Sub
The myThread method will continue running until either you run a t.stop() from somewhere else in your code or you call an "Exit Loop" from within the Do Loop.
Please Note:
If you are updating controls on a form from a threaded function you will need to use a Delegate, I can send you an example if you cannot find one.
Also if you have a number of threads accessing the same resources you might need to use a Mutex to limit access violations.
Hope this helps.
|
|
|
|
|
Also might I add, from experience you might want to monitor how much memory your application uses after 1 hour of your software running then 2.... Just in case there are any memory leaks.
Hope this helps
|
|
|
|
|
Hi All,
I'm using ListView to show several columns of data. (View = Details)
Everything worked fine until I wanted to let the user to hide/show certain column(s).
I hide the column this way:
ListView1.Columns.Remove()
Problem is to get the column correctly visible again, so that columnheaders are correctly ordered into subitem-columns.
When I use ListView1.Columns.Insert() or ListView1.Columns.Add() to get the column visible again it links the columnheader to wrong subitem-column.
Is there any way to link a columnheader into subitem-column?
|
|
|
|
|
When you use remove, you are not hiding it, you are deleting it from the collection.
When you use insert, you can specifying the position you want to add the column, have you tried that?
Why not set the column width to 0 instead to hide it? that way it will remain in the same place.
|
|
|
|
|
Further to my original response, i just did a quick test and can confirm that if you insert a column at the appropriate index, the subitems remain correctly with the columns;
e.g. lv.removeat(2), lv.insert(2, "Col 3")
As a quick demo, create a form, add a listview in details view, add three pushbuttons, drop in the following code and run the app;
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Add some columns
ListView1.Columns.Add("Col 1")
ListView1.Columns.Add("Col 2")
ListView1.Columns.Add("Col 3")
ListView1.Columns.Add("Col 4")
'Add some test data
Dim x As New ListViewItem
x.Text = "1"
x.SubItems.Add("2")
x.SubItems.Add("3")
x.SubItems.Add("4")
ListView1.Items.Add(x)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
ListView1.Columns.RemoveAt(2)
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
ListView1.Columns.Insert(2, "col 3")
End Sub
And you will see the test data remains in the 1,2,3,4 sequence before and after the remove and insert operations.
|
|
|
|
|
Thanks for Your answer.
To hide a column via setting column width is not an option, because the user is and must be able to resize the column width.
In Your example, if You first remove 2, 3 and 4 columns. And then insert only 4. column back, it causes an error.
Problem is, that there are more subitems than there are columns. And in that case the columnheader can't necessarily be inserted over correct subitem.
|
|
|
|
|
There does not appear to be anywayto map the subitems to columns.
However this IS doable using the width. refere back to the orginal form example i gave earlier and add the code below;
You will see, when you remove a column its width is set to 0 and added to a list of locked columns, then when the user tries to resize the locked column the columnresizing event checks if the column is in the locked collection, cancel the event and sets the width to 0.
Public Class Form1
Dim listLocked As New List(Of Integer) 'Locked columns
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Add some columns
ListView1.Columns.Add("Col 1")
ListView1.Columns.Add("Col 2")
ListView1.Columns.Add("Col 3")
ListView1.Columns.Add("Col 4")
'Add some test data
Dim x As New ListViewItem
x.Text = "1"
x.SubItems.Add("2")
x.SubItems.Add("3")
x.SubItems.Add("4")
ListView1.Items.Add(x)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim colIndex As Integer = 2
ListView1.Columns(colIndex).Width = 0
If Not listLocked.Contains(colIndex) Then listLocked.Add(colIndex)
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim colIndex As Integer = 2
ListView1.Columns(colIndex).Width = 25
If listLocked.Contains(colIndex) Then listLocked.Remove(colIndex)
End Sub
Private Sub ListView1_ColumnWidthChanging(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnWidthChangingEventArgs) Handles ListView1.ColumnWidthChanging
'Check column is not hidden
If listLocked.Contains(e.ColumnIndex) Then
e.Cancel = True
e.NewWidth = 0
End If
End Sub
End Class
|
|
|
|
|
Yes, this seems to be the final solution.
Actually I had this kind of solution earlier for hiding columns.
But then something happened and ListView ColumnWidthChanging event stopped working. I mean that ColumnWidthChanging event does not fire att all.
And I have not found any solution for that.
Do You have any ideas how to get this ColumnWidthChanging-event problem fixed?
|
|
|
|
|
No idea what would stop the columnwidthchanging event, other than some code you added to your original solution getting in the way.
|
|
|
|
|
Maybe if you block some columns to resize.
This is my code to block them standard all with property to release some
Imports System.Runtime.InteropServices
Namespace Controls
Public Class ListView_FixColumns
Inherits ListView
Private _KolommenVrij(1024) As Boolean
Public Const WM_NOTIFY As Integer = &H4E
Public Const HDN_FIRST As Integer = 0 - 300
Public Const HDN_BEGINTRACKA As Integer = HDN_FIRST - 6
Public Const HDN_BEGINTRACKW As Integer = HDN_FIRST - 26
<StructLayout(LayoutKind.Sequential)> Public Structure NMHDR
Public hwndFrom As IntPtr
Public idFrom As Integer
Public code As Integer
End Structure
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_NOTIFY Then
Dim hdr As NMHDR = CType(m.GetLParam(GetType(NMHDR)), NMHDR)
If hdr.code = HDN_BEGINTRACKA OrElse hdr.code = HDN_BEGINTRACKW OrElse hdr.code = HDN_DIVIDERDBLCLICKW Then
Dim nmHeader As NMHEADER = CType(m.GetLParam(GetType(NMHEADER)), NMHEADER)
If Not _FreeColumns(nmHeader.iItem) Then
m.Result = New IntPtr(1)
Exit Sub
End If
End If
End If
MyBase.WndProc(m)
End Sub
Public Property AllowColumnResize(ByVal Column As Integer) As Boolean
Get
Return _KolommenVrij(Column)
End Get
Set(ByVal value As Boolean)
_KolommenVrij(Column) = value
End Set
End Property
End Class
End Namespace
If you add a property to select witch columns may not be blocked it will do
|
|
|
|
|
Thanks in advance.
I am using SendKeys to Handle an application it works fine when i call SendKeys Functionality on Button click , means when user clicks , but when i calls it
on Form load it does not work and goes to wrong menu
Any SuggestionBest Regards,
SOFTDEV
If you have knowledge, let others light their candles at it
|
|
|
|
|