Text length in a WinForms ToolTip - winforms

how to set the max length of a text in a WinForms ToolTip?
I have a String with about 300 chars, but my ToolTip displays only 264 of them...
Greets,
Jürgen

You could add NewLine a few times in your ToolTip string like this so that it does not go all the way across the screen.
The string in this code is 434 characters long.
:-)
Just run this code to try it please:>>
Imports System.Environment
Public Class Form1
Friend WithEvents myToolTip As New ToolTip
Private Sub Form1_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseHover
Dim someText As String = _
"Hello World!! Hi everyone!! Good day, good evening or goodnight, wherever you are in the world!! :-) :-D" & NewLine & _
"Hello World!! Hi everyone!! Good day, good evening or goodnight, wherever you are in the world!! :-) :-D" & NewLine & _
"Hello World!! Hi everyone!! Good day, good evening or goodnight, wherever you are in the world!! :-) :-D" & NewLine & _
"Hello World!! Hi everyone!! Good day, good evening or goodnight, wherever you are in the world!! :-) :-D"
Me.Text = someText.Length.ToString
myToolTip.Show(someText, Me, 5000)
End Sub
End Class

I had this same issue (it happened to be with a DataGridView cell) and the default ToolTip text (i.e. the text content of the cell) was indeed being truncated.
For me, it started working correctly when I set the ToolTip text explicitly (all of the answers I see do this). What I think is subtle is that the default ToolTip text uses the same cell content, only the default handler does truncate it as noted in the original question. By overriding the event and setting the ToolTip text (even though it's exactly the same cell text!) now the default length restriction seems to go away.
protected override void OnCellToolTipTextNeeded(DataGridViewCellToolTipTextNeededEventArgs e)
{
if((e.RowIndex >= 0) && (e.ColumnIndex >= 0))
{
// By setting this explicitly we can make the ToolTip length
// longer even though the content is exactly the same.
e.ToolTipText = this[e.ColumnIndex, e.RowIndex].Value.ToString();
}
base.OnCellToolTipTextNeeded(e);
}
Other controls will fire different events of course, but it should hold that if you put the text onto the tool tip yourself then you can circumvent the truncation that occurs with any default ToolTip.

I know this is an old question and I'm not sure if the following functionality existed at that time, but for those searching for this, I noticed that if the Tooltip text is very long, it may not get displayed at all, and after some trying, found that this helps:
// 999 = just an arbitrary number to test for possible very long text, may have to fiddle with that (maybe screen width) !
// 456 = also arbitrary, change to your liking !
// tooltip.GetToolTip((sender as ToolTip).Tag as Control) is because I have multiple controls using the same Tooltip, so I set the Tooltip.Tag to the control that will call Tooltip.Show(...). If you have 1 tooltip per control than just replace it with the control in question.
tooltip.Popup += (sender, e) =>
{
if (e.ToolTipSize.Width > 999)
{
Size s = TextRenderer.MeasureText(tooltip.GetToolTip((sender as ToolTip).Tag as Control), SystemFonts.SmallCaptionFont);
e.ToolTipSize = new Size(456, s.Height * 3); // * 3 turned out to work for SystemFonts.SmallCaptionFont
}
};

Related

How do I allow a "SPACE" character in an AutoComplete JavaFX uneditable ComboBox?

When I type a SPACE character in an AutoComplete ComboBox, I can get the space character to be accepted except the addEventFilter code I'm using to manage it multiplies and inserts a space for each character previously typed prior to the space. You can see a screen shot example below where 3 spaces were added after the 3 characters (ive), then 4 spaces added after I include an additional charater (t), each after typing a single SPACE, and the spaces only appear after I type the next character (e.g. 'm').
I did try this with the ContolsFX AutoComplete, but it cannot handle the uneditable ComboBox - and couldn't find anything to the contrary. In the online cases I research, it was recommended to use the ComboBox's popup skin - addEventFilter to manage the SPACE character event. In nearly all the cases it was to consume() and prevent the space from selection and closing. I did not find anything that strictly allowed the space to be entered. I've tried adding the SPACE in code prior to and after this Event Code but the addEventFilter event.consume() will remove it. The SPACE character will only appear if I manage its addition within the addEventFilter method. I've tried different events such as KeyEvent.ANY, KeyEvent.KEY_TYPED, and KeyEvent.KEY_RELEASE and read the documentation on the KeyEvent, but only KeyEvent.KEY_PRESSED seems to allow the SPACE character, it just multiplies the number of spaces, and doesn't insert until the next text character.
ComboBoxListViewSkin cbSkin = cbSkin = new ComboBoxListViewSkin(cmb);
// cmb is the ComboBox
cbSkin.getPopupContent().addEventFilter(KeyEvent.KEY_PRESSED, (event) -> {
if(event.getCode() == KeyCode.SPACE){
filter += " ";
event.consume();}
});
I was able to solve my problem. The event code needed to be a part of the ComboBoxAutoComplete constructor and not part of the onKeyPressed event.
private ComboBoxListViewSkin cbSkin;
public ComboBoxAutoComplete(ComboBox<T> cmb) {
this.cmb = cmb;
cbSkin = new ComboBoxListViewSkin(cmb);
originalItems = FXCollections.observableArrayList(cmb.getItems());
cmb.setOnKeyPressed(this::handleOnKeyPressed);
cmb.setOnHidden(this::handleOnHiding);
cmb.setSkin(cbSkin);
cbSkin.getPopupContent().addEventFilter(KeyEvent.KEY_PRESSED, (event) -> {
if(event.getCode() == KeyCode.SPACE){
filter += " ";
event.consume();}
});
}

Allow edits from different users appear in different color inside memo box : Microsoft Access 2010

I have a memo field which contains rich text. I am able to identify a user and change all the text in the box instead of just the text they added.
I am looking to write code which allows the text to be edited and after update , the edited text will appear a different color than the original text in the memo field.
I have tried :
Dim strNew As String
Dim strOld As String
If Me.txt_username_id = "grant" Then
strOld = Me.Form!txtnotesaboutproduct1.OldValue.ForeColor = vbBlack<br/>
strNew = Me.Form!txtnotesaboutproduct1.ForeColor = vbRed
End If
I have also tried
Dim ctlOld As TextBox<br/>
Set ctlOld = Me.Form!txtnotesaboutproduct1
If Me.txt_username_id = "grant" Then
ctlOld = Me.Form!txtnotesaboutproduct1.OldValue.ForeColor = vbRed
End If
Generally, I do this with a continuous subform for Notes, so that I can hold the data, date and user, rather than just one formatted text box. Though I do realize this might be a lot more real estate that you might have, you can use a conditional format within the subform. I do agree that if it is possible, you'll likely need to use HTML and not .Forecolor, which will change the entire box.

SpeechSynthesizer audio to text as its spoken

I Am currently working on a project where I want to have the SpeechSynthesizer speak a text. I also want a textblock to display the words as they are spoken. This is so you can read along if you don't understand the Speech Synthesizer.
So basically the problem is that i cant find a efficient way to append every letter to a text within a textbox right when its spoken by the Speech Synthesizer. So it looks like the Speech Synthesizer is typing along with what he is saying.
Example
If I would do this:
SpeechSynthesizer x = new SpeechSynthesizer();
x.SpeakAsync("Hello there");
I want the textbox text to write along as the words are spoken by the x (SpeechSynthesizer ). Something like this:
http://youtu.be/hx6JL7PsLrg?t=1m56s
As Eric mentioned, you have to use the SpeechSynthesizer.SpeakProgress event:
For Example:
var ss = new SpeechSynthesizer();
ss.SpeakProgress += (sender, args) => txtBox.Text += args.Text;
ss.Speak("Hello this is " + true);
This is kind of hacky (and isn't guaranteed to do letter-by-letter), but you could use the PhonemeReached event as a hint to display the next letter (and stop at word breaks) and then use the SpeakProgress event to generate the remaining letters in the word. If you're using SSML, you'll need to skip over markup, of course.

Printing text in Silverlight that measures larger than page

I have a silverlight application that allows people to enter into a notes field which can be printed, the code used to do this is:
PrintDocument pd = new PrintDocument();
Viewbox box = new Viewbox();
TextBlock txt = new TextBlock();
txt.TextWrapping = TextWrapping.Wrap;
Paragraph pg = new Paragraph();
Run run = new Run();
pg = (Paragraph)rtText.Blocks[0];
run = (Run)pg.Inlines[0];
txt.Text = run.Text;
pd.PrintPage += (s, pe) =>
{
double grdHeight = pe.PrintableArea.Height - (pe.PageMargins.Top + pe.PageMargins.Bottom);
double grdWidth = pe.PrintableArea.Width - (pe.PageMargins.Left + pe.PageMargins.Right);
txt.Width = grdWidth;
txt.Height = grdHeight;
pe.PageVisual = txt;
};
pd.Print(lblTitle.Text);
This simply prints the content of the textbox on the page however some of the notes are spanning larger than the page itself causing it to be cut off. How can I change my code to measure the text and add more pages OR is there a better way to do the above where it will automatically create multiple pages for me?
There are several solutions to your problem, all of them under "Multiple Page Printing Silverlight" on Google. I was having a similar problem and tried most of them. The only one that worked for me was this one:
http://www.codeproject.com/Tips/248553/Silverlight-converting-to-image-and-printing-an-UI
But honestly you should look at Google first and see whether there are better solutions to your specific problem.
Answering your question, there is a flag called HasMorePages that indicates you need a new page. Just type pe.HasMorePages and you will see.
Hope it helps
First you need to work out how many pages are needed
Dim pagesNeeded As Integer = Math.Ceiling(gridHeight / pageHeight) 'gets number of pages needed
Then once the first page has been sent to the printer, you need to move that data out of view and bring the new data into view ready to print. I do this by converting the whole dataset into an image/UI element, i can then adjust Y value accordingly to bring the next set of required data on screen.
transformGroup.Children.Add(New TranslateTransform() With {.Y = -(pageIndex * pageHeight)})
Then once the number of needed pages is reached, tell the printer to stop
'sets if there is more than 1 page to print
If pagesLeft <= 0 Then
e.HasMorePages = False
Exit Sub
Else
e.HasMorePages = True
End If
Or if this is too much work, you can simply just scale all the notes to fit onto screen. Again probably by converting to UI element.
Hope this helps

Loop through Textboxes in access database

I have an Access database that I want to loop through certain textboxes in order to do a calculation and display the answer in a seperate textbox. When I attempt to loop it loops through every control on my form (with the Form.Controls) method. I would like to only loop through 4 specific textboxes (txtbx1, txtbx2, txtbx3, txtbx4) when my button is clicked.
Explanation...
TextBox_A contains a Number
Upon button click take the number from TextBox_A, Multiply by 2800, then Divide by 12
Display the answer to the calculation in txtbx1.
I would do this for each of the 4 textboxes named above. Then have a "Total" textbox that adds up the total from each textbox (txtbx1, txtbx2, txtbx3, txtbx4). Please help, new to this and at a complete loss.
Every control has got a Tag property. Set the Tag property for textboxes whose values you want to include in your algorithm (say to "INClUDE"). It's free format text, so you can put what you like.
Then write code attached to some form event similar to this:
Dim c As Control
Dim txt As TextBox
For Each c In Me.Controls
'check it's a text box ...
If TypeOf c Is TextBox Then
'see if including ...
Set txt = c
If Len(txt.Tag) > 0 Then
'do something here (I've coloured, to show works)
txt.BackColor = 10
End If
End If
Next c
I've set an extra variable txt to refer to the textbox in question, so that I can get at the TAG property using autocompletion (I believe this is called a narrowing conversion!).
It would be easier if you rename TextBox_A (_B / _C etc) to TextBox_1 / _2 / _3 etc.
And then try this:
Dim i As Integer
For i = 1 To 4
Controls("txtbx" & i) = Val(Controls("TextBox_" & i)) * 2800 / 12
Next
Otherwise, this would work too, but it is not well readable:
= Val(Controls("TextBox_" & Chr(Asc("A") + i - 1))) * 2800 / 12

Resources