I got an userControl that contains a searchBox.
This UserControl is inside another one.
I got a strange behavior while i'm searching, because the suggestionCollection works in a strange way.
Example :
in the searchBox i write something all works perfectly, if i choose the item it also works.
But if i try to use backspace (after the choose) i got no suggestion.
I cannot understand why it doesn't work.
That's the code
//var deferral = args.Request.GetDeferral(); //it seems to not influence the behavior
var suggestionCollection = args.Request.SearchSuggestionCollection;
try
{
TransporterExt tr_search = new TransporterExt();
//queryText is a string inserted in the searchBox
if (string.IsNullOrEmpty(queryText)) return;
tr_search.name = queryText;
suggested.Clear(); //that's a collection..
//just a search that return a collection of objects TransporterExt
querySuggestions = await TransporterService.Search_StartsWith(tr_search);
if (querySuggestions.Count > 0)
{
int i = 0;
foreach (TransporterExt tr in querySuggestions)
{
string name = tr.name;
string detail = tr.trId.ToString();
string tag = i.ToString();
string imageAlternate = "imgDesc";
suggestionCollection.AppendResultSuggestion(name, detail, tag, imgRef, imageAlternate);
this.suggested.Add(tr);
i++;
}
}
}
catch (System.ArgumentException exc)
{
//Ignore any exceptions that occur trying to find search suggestions.
Debug.WriteLine(exc.Message);
Debug.WriteLine(exc.StackTrace);
}
//deferralComplete(); //it seems to not influence the behavior
The problem is that: all the variables have the right value, but the suggestion panel appears only if i make a particular search: it appears when i change the first letter of search, or after an wrong seach
What appends when i make a search
What appends if i use the backspace, and i what i want to fix
As i said, all works perfectly, after the "backspace" action the suggestionCollection got the right value...but the panel is missing.
Could someone help me?
You can use SearchBox and SuggestionRequested event to fire the event when type on the SearchBox. I will show an Example
<SearchBox x:Name="SearchBoxSuggestions" SuggestionsRequested="SearchBoxEventsSuggestionsRequested"/>
and write the SearchBoxEventsSuggestionsRequested handler in the code behind
private void SearchBoxEventsSuggestionsRequested(object sender, SearchBoxSuggestionsRequestedEventArgs e)
{
string queryText = e.QueryText;
if (!string.IsNullOrEmpty(queryText))
{
Windows.ApplicationModel.Search.SearchSuggestionCollection suggestionCollection = e.Request.SearchSuggestionCollection;
foreach (string suggestion in SuggestionList)
{
if (suggestion.StartsWith(queryText, StringComparison.CurrentCultureIgnoreCase))
{
suggestionCollection.AppendQuerySuggestion(suggestion);
}
}
}
}
You can add the keyword to SuggestioList, and it will show in the dropdown when you type on the Searchbox.
Create the SuggestionList
public List<string> SuggestionList { get; set; }
initialize the list
SuggestionList = new List<string>();
and add keywords to the list
SuggestionList.Add("suggestion1");
SuggestionList.Add("suggestion2");
SuggestionList.Add("suggestion3");
SuggestionList.Add("suggestion4");
SuggestionList.Add("Fruits");
Thanks.
Related
I cant seem to figure out how to put the value text into a texbox.Text on Webbrowser C# because with this website the value changes and there are duplicates of the input code and cant pinpoint Webbrowser to put the changing value username in a textbox.Text as seen in screenshot below.
I hope someone knows how to do this with the Webbrowser in C#
Thanks in advance.
Problem Screenshot
This is the website I am trying to get the username from: fakepersongenerator
You'd need to manually scan through the DOM and find the element based on it's xpath. Like this:
webBrowser.DocumentCompleted += (o, e) =>
{
var frame1 = webBrowser.Document.Body.GetElementsByClassName("frame-1");
if (frame1.Count > 0)
{
var rows = frame1[0].GetElementsByClassName("row no-margin");
if (rows.Count > 4)
{
var usernameForm = rows[4].GetElementsByClassName("form-control");
if (rows.Count > 0)
{
// Do something with value here
Console.WriteLine(usernameForm[0].GetAttribute("value"));
}
}
}
};
webBrowser.Navigate("http://www.fakepersongenerator.com/Index/generate");
Extension class to :
internal static class Utils
{
internal static List<HtmlElement> GetElementsByClassName(this HtmlElement doc, string className = "")
{
var list = new List<HtmlElement>();
foreach (HtmlElement e in doc.All)
if (e.GetAttribute("className") == className)
list.Add(e);
return list;
}
}
There isn't really a way in the default web browser to detect changes after a page load, so if you wanted to monitor for changes, you'd have to set up a BackgroundWorker or Timer to poll the browser and manually look for a value change.
I have this code for a textbox on a website:
<textarea class="chat_input">
Enter text for chat here
</textarea>
What I am trying to do, is to put text into it. On a different question, a person showed how to click a link that was a class with this code:
foreach (Node el in webKitBrowser1.Document.GetElementsByTagName("a"))
{
if (((Element) el).GetAttribute("id") == "lnkId")
{
string urlString = ((Element) el).Attributes["href"].NodeValue;
webKitBrowser1.Navigate(urlString);
}
}
I tried adapting it for this code here:
message = txtMessage.Text;
foreach(Node txt in wb.Document.GetElementsByTagName("textarea"))
{
if(((Element)txt).GetAttribute("Class") == "chat_input")
{
((Element)txt).SetAttribute("Value", message);
}
}
When I debugged it, it went though the code 5 times, which is how many textarea's there was. Does anyone know why it does not fill the textbox?
You need to not use SetAttribute, but set the TextContent property instead.
So:
if(((Element)txt).GetAttribute("Class") == "chat_input")
{
((Element)txt).TextContent = message;
}
I have a ListView in a C# based win-form project. Is it possible to limit the maximum length of the title of all ListViewItem inside the ListView ?
UPDATE
I mean the input length , I set the item to editable , so users can rename the items
UPDATE2
Right , It's called "the text" of that item , not the title.
You can utilise the label after edit event of a listview. Here is a sample.
private void listview1_AfterLabelEdit(object sender, LabelEditEventArgs e)
{
try
{
const int maxPermittedLength = 1;
if (e.Label.Length > maxPermittedLength)
{
//trim text
listview1.Items[e.Item].SubItems[0].Text = listview1.Items[e.Item].SubItems[0].Text.Substring(0, maxPermittedLength); //or something similar
//or
//show a warning message
//or
e.CancelEdit = true; //cancel the edit
}
}
catch (Exception ex)
{
}
}
Remember, its tricky, not straightforward, you will have to take care of a few exceptions, but thats homework.. The above code is not a working code, but you have the idea now how to go about it. Read the documentation well, it has a nice example and a warning associated with this event.
What do you mean ListViewItem's title ? is it the item text you mean ? I believe whatever retrievable is fixable and controllable. If it is the item text, you can write a check method
public string SimplifyTxt(string input)
{
if(input.Length>LIMIT_NUMBER)
{
//please shorten the string before display
}
return retStr;
}
and it then can be assigned as
listview1.items.add(new Listviewitem{Text=retVal});
I have a ListBox control populated with branches of a large retail chain. The staff using the system have to log in to the relevant branch, and I would like them to be able to search the ListBox to find their branch.
I have created an event handler for when text in the search box changes, and attempted to use code sound on StackOverflow already:
private int lastMatch = 0;
private void txtSearch_TextChanged(object sender, EventArgs e)
{
int x = 0;
string match = txtSearch.Text;
if (txtSearch.Text.Length != 0)
{
bool found = true;
while (found)
{
if (lbBranches.Items.Count == x)
{
lbBranches.SetSelected(lastMatch, true);
found = false;
}
else
{
lbBranches.SetSelected(x, true);
match = lbBranches.SelectedValue.ToString();
if (match.Contains(txtSearch.Text))
{
lastMatch = x;
found = false;
}
x++;
}
}
}
}
When I compile and start typing into the search box, I get this error:
Object reference not set to an instance of an object.
The line in question is:
match = lbBranches.SelectedValue.ToString();
I have no idea what could be wrong there, anyone got an idea?
Thanks!
SelectedValue of the listbox will only return a value if you have specified the ValueMember property of the listbox to indicate a property from which you would like to read the value for the selected item. The property you want to use in this case is SelectedItem:
match = lbBranches.SelectedItem.ToString();
when the user is entering text it's possible that no value has been selected (hence the error) -- keep in mind that what is being entered by the user has no mandatory or direct association with selections in the controls listbox sub-element
it's possible what you're doing might be simpler to implement with a full combo-box control and I think some of the examples at MSDN could be very helpful for you as well
I am using two forms, where one is a rich text editor with menus and a rich text box and the second form is for search and replace and contains four button and two text boxes. I have managed to do the find button but I am having problems with Find Next. I am using C# Windows Forms.
Here is the code I am using for Find:
private void button1_Click(object sender, EventArgs e)
{
RichTextBox frm1TB = ((Form1)this.Owner).txtDisplay;
int foundAt = frm1TB.Text.IndexOf(searchText.Text);
if (foundAt == -1)
{
MessageBox.Show("Not Found");
}
else
{
frm1TB.SelectionStart = foundAt;
frm1TB.SelectionLength = searchText.TextLength;
frm1TB.Focus();
}
}
Find next would be something like the following:
if (frm1TB.Text.Length >= frm1TB.Text.SelectionStart + frm1TB.Text.SelectionLength)
{
int foundAt = frm1TB.Text.IndexOf(
searchText.Text,
frm1TB.Text.SelectionStart + frm1TB.Text.SelectionLength);
}
You need to remember index at which you found your previous entry (or even better, at which you should start find next search) and then simply use IndexOf(string, int) overload, which allows you to start search at specified position. First, simply add next search start index field to your class:
private int nextSearchStartIndex;
Now, your Find method needs to keep update this index appropriately:
if (foundAt == -1)
{
this.nextSearchStartIndex = 0;
MessageBox.Show("Not Found");
}
else
{
this.nextSearchStartIndex = foundAt + searchText.TextLength;
// ...
}
And FindNext becomes trivial:
// ...
var foundAt = frm1TB.Text.IndexOf(searchText.Text,
this.nextSearchStartIndex);
// Here you can use exactly same update index logic as in Find
You can't use the IndexOf() method for it, you have to switch to Regular Expressions.
Here is an example how you can easily get all the search entries in RichtBox.Text:
using System.Text.RegularExpressions;
Regex re = new System.Text.RegularExpressions.Regex(searchText.Text.ToString(),RegexOptions.None);
MatchCollection mc = re.Matches(frm1TB.Text.ToString());
foreach (var ma in mc)
{
//do what you want
}