a question for agraham

Ricky D

Well-Known Member
Licensed User
Gday mate.

I'm converting the vb version of autocomplete into C# using VS2005.

this line in VB
If item.ToUpper.StartsWith(strg) Then

the StartsWith doesn't seem to be in C#

here is the VB code block
If item.ToUpper.StartsWith(strg) Then
found = True
Exit For
End If

how should I write this in C#?

regards, Ricky
 

Ricky D

Well-Known Member
Licensed User
thanks, another one

what's the equivalent of Exit For ?

regards, Ricky
 

Ricky D

Well-Known Member
Licensed User
thanks

thanks again. Now to test tomorrow. Sleep time now!

regards, Ricky
 

Ricky D

Well-Known Member
Licensed User
Another one - keyup event not working

Hi again agraham.

this is the keyup code for the internal textbox :

private void txtText_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
string strg = txtText.Text.ToUpper();
string cboitem="";
bool found = false;
int jj=0;

System.Windows.Forms.MessageBox.Show("hey");
if (e.KeyData == Keys.Back)
{
e.Handled = true;
return;
}

if (mAutoCompleteOn == false)
{
e.Handled = true;
return;
}

for (int j = 0; j < cboCombo.Items.Count; j++)
{
cboitem = (string)cboCombo.Items[j];
if (cboitem.ToUpper().StartsWith(strg))
{
jj = j;
found = true;
break;
}
}

if (found)
{
txtText.Text = cboitem;
txtText.SelectionStart = strg.Length;
txtText.SelectionLength = txtText.Text.Length - strg.Length;
cboCombo.SelectedIndex = jj;
}
}

can you see why this isn't being fired when I type in the text portion of the control? I put the messagebox there for debugging.

regards, Ricky
 

agraham

Expert
Licensed User
Probably because you haven't added the event delegate to the textbox event in your constructor.

B4X:
TextBox yourtextbox; // private variable
  ...
yourtextbox = new TextBox (); // in the constructor 
yourtextbox.KeyUp += txtText_KeyUp; // add a delegate to the event
  ...
 

Ricky D

Well-Known Member
Licensed User
that was it

again many thanks. It's harder than vb so what's the attraction to C#? Is it just that you have done C before?

In my formative years I started on Z80 processors doing assembly and turbo pascal. When Dos came along then windows I'd see code written in C that was so unreadable that it turned me off it way back then. No one would be kind enough to explain it in a simple way. Hence I like the "verbose" languages that came along like pascal and basic. I found cobol way too verbose and disliked it for being on the other end of the verbosity scale where c was least to cobol largest lol

I taught myself how to program and have seen clipper on pc, pascal on pc, Rally on Vax/VMS plus Cobol on same. In college I did a bit of Fortran too.

My how the landscape of IT has changed.

regards, Ricky
 

Ricky D

Well-Known Member
Licensed User
hi Erel

do you program B4ppc in C# for the desktop and device?

I can't get this autocomplete working in C# and can't see how to debug what's going on inside the dll :(

it's working in vb so I'll leave it at that I think.

Here is the code that's not working

if (found)
{
txtText.Text = cboitem;
txtText.SelectionStart = strg.Length;
txtText.SelectionLength = txtText.TextLength - strg.Length;
cboCombo.SelectedIndex = jj;
}

what it does is when I type W for World it brings back the World string and places the caret at the start of the text instead of at the end. It also doesn't select the orld part of the text.

regards, Ricky
 
Last edited:

Ricky D

Well-Known Member
Licensed User
here's the keyup code

private void txtText_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
inautocomplete = true;
string strg = txtText.Text.ToUpper();
string cboitem="";
bool found = false;
int jj=0;

if (e.KeyData == Keys.Back)
{
e.Handled = true;
inautocomplete = false;
return;
}

if (mAutoCompleteOn == false)
{
e.Handled = true;
inautocomplete = false;
return;
}

for (int j = 0; j < cboCombo.Items.Count; j++)
{
cboitem = (string)cboCombo.Items[j];
if (cboitem.ToUpper().StartsWith(strg))
{
jj = j;
found = true;
break;
}
}

if (found)
{
txtText.Text = cboitem;
txtText.SelectionStart = strg.Length;
txtText.SelectionLength = txtText.TextLength - strg.Length;
cboCombo.SelectedIndex = jj;
}
inautocomplete = false;
}
 

agraham

Expert
Licensed User
I can't get this autocomplete working in C# and can't see how to debug what's going on inside the dll :(
You need to compile in debug mode. Put your B4ppc test program in the project debug directory and add the dll as a component. Then run the app either in the IDE or compiled - you may need a temporary stop with a message box if it runs straight into the problem area. You can attach the VS debugger to the process, Debug -> Attach to Process, and can now set breakpoints and single-step your dll code. This works whatever language you are using.

If you post the cs file as far as you got I will critique it for you if you wish.

I remember Z80 Assembler and Turbo Pascal 3 on CP/M and TRSDOS/LDOS with great affection. The good old days, but times change - sigh!
 

agraham

Expert
Licensed User
You were pretty much there. However you missed out testing if Basic4ppc had set an event in each of your four events.
B4X:
if (SelectionIndexChanged != null)
    SelectionIndexChanged(eventObjectSelectionIndexChanged, null);
The events were therefore calling a null delegate which seemed to be causing the problem. Interestingly as soon as I attached the VS debugger it complained about Null Reference exceptions at the four event calls - but without the debugger attached it did not throw those exception but didn't work properly either - I don't understand that one :confused:
 

Ricky D

Well-Known Member
Licensed User
ok

I admit I downloaded your controlsex.cs and took examples from there. If not null then what should they be?

I don't understand.

regards, Ricky
 

agraham

Expert
Licensed User
To implement a Basic4ppc event (not necessarily a .NET originated event) you declare a public EventHandler object, a private object array and your event method.

B4X:
public event EventHandler GotFocus;
private object[] GotFocusEventObject;

private void GotFocusEvent(object sender, EventArgs e)
{
    if (GotFocus != null)
    {
        GotFocus(GotFocusEventObject, null);
    }
}
In your constructor you initialise your object array. Additionally, if you want to pass on an event from a .NET object you need to add your event code to that objects event, otherwise you can just call the event code from in the library. In this case it doesn't need those two parameters, they are there to match what the .NET object signature expects
B4X:
GotFocusEventObject= New Object() {this, "GotFocus"}
something.GotFocus += GotFocusEvent;
At runtime if a Basic4ppc event exists for that event Basic4ppc sets the public EventHandler to its own event handler method, otherwise the EventHandler remains set to the default of null. Your event code needs to test this EventHandler for the null value before calling it (I think the VB RaiseEvent does this test for you). If it is not null you call it, passing who you are "this" and the the name of the event to Basic4ppc. In turn Basic4ppc then sets the Sender name from "this" and calls the correct Basic4ppc Sub determined by the Sender and the event name. The name of the EventHandler must match the name of the event that you will pass so that everything matches up properly.
 

Ricky D

Well-Known Member
Licensed User
ok, i'll have a closer look and try to understand.

but what about the keyup event? It is firing but it's not doing what I need - that is to accept a key, check .Text of textbox and see if it's in combobox. If so .Text gets the combobox item. Then the selectionstart and selectionlength properties are set.

Currently this doesn't work

regards, Ricky
 

Erel

Administrator
Staff member
Licensed User
I've attached a small Basic4ppc program that demonstrates a one word autocomplete.
The code is built in such way that you can easily reuse the module in your own program.
Example of using this module:
B4X:
Sub App_Start
    Form1.Show
    ArrayList1.Add("World")
    ArrayList1.Add("Worm")
    ArrayList1.Add("Cat")
    ArrayList1.Add("Cattle")
    ArrayList1.Add("Castle")
    'Main - current module, TextBox1 - the autocomplete textbox
    'ArrayList1 - the list of words
    MAutoComplete.Set("Main","TextBox1","ArrayList1")
    MAutoComplete.Set("Main","TextBox2","ArrayList1")
End Sub
In the module I've used a Hashtable from agraham's collections library to hold pairs of textboxes and arraylists.
This allows us to use this module with any number of textboxes.
 
Top