How do I add a click event handler to a TextBox's DeleteButton? - winrt-xaml

I have a TextBox in one of my Windows Runtime app's Pages. When there is text in the TextBox, it shows a black cross which, when clicked, clears the TextBox. Apparently this is the DeleteButton from the default template, and there are loads of questions on SO about how to remove it. I don't want to remove it, but I do want to add an event handler so I know when it is clicked.
How do I add a click event handler to a TextBox's DeleteButton? I'd prefer an answer that saves me having to make a copy of the template.

<TextBox x:Name="TestTextBox" Loaded="TestTextBox_Loaded" Width="300" Height="100"></TextBox>
The easiest way is to use the VisualTreeHelperExtension from the WinRTXamlToolkit (or as NuGet package).
With the TreeHelper you can easy access the button:
private void TestTextBox_Loaded(object sender, RoutedEventArgs e)
{
var deleteButton = TestTextBox.GetChildByName<Button>("DeleteButton");
deleteButton.Click += deleteButton_Click;
}
void deleteButton_Click(object sender, RoutedEventArgs e)
{
throw new NotImplementedException();
}
I use this function:
public static T GetChildByName<T>(this DependencyObject parent, string childName) where T : DependencyObject
{
// Confirm parent and childName are valid.
if (parent == null) { return null; }
T foundChild = null;
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
// If the child is not of the request child type child
var childType = child as T;
if (childType == null)
{
// recursively drill down the tree
foundChild = GetChildByName<T>(child, childName);
// If the child is found, break so we do not overwrite the found child.
if (foundChild != null) { break; }
}
else if (!string.IsNullOrEmpty(childName))
{
var frameworkElement = child as FrameworkElement;
// If the child's name is set for search
if (frameworkElement != null && frameworkElement.Name == childName)
{
// if the child's name is of the request name
foundChild = (T)child;
break;
}
// Need this in case the element we want is nested
// in another element of the same type
foundChild = GetChildByName<T>(child, childName);
}
else
{
// child element found.
foundChild = (T)child;
break;
}
}
return foundChild;
}

Related

Worker stop in the middle and not updating progress bar

I'm trying to load information with worker and using reportprogress to update progress bar until finshing, but the worker stop working and doesn't finish the for loop or continue after several minutes. I don't know what's the problem and I tried every post here I can find related to this problem and didn't get anything. I hope I can finally get an answer posting my problem here.
Here's the relevant code:
public class Class1
{
public BackgroundWorker unit_read_data_setting_Worker;
public Class1()
{
unit_read_data_setting_Worker = new BackgroundWorker();
unit_read_data_setting_Worker.WorkerReportsProgress = true;
unit_read_data_setting_Worker.WorkerSupportsCancellation = false;
unit_read_data_setting_Worker.DoWork += new DoWorkEventHandler(unit_read_data_setting);
unit_read_data_setting_Worker.ProgressChanged += new ProgressChangedEventHandler(_update_progress);
unit_read_data_setting_Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Completed);
}
public void unit_read_data_setting(object sender = null, DoWorkEventArgs e = null)
{
lock (FamilyTreeViewModel.Lock_ParameterList)
{
ObservableCollection<Parameter_UC_ViewModel> _internal_parameter_list =
FamilyTreeViewModel.GetInstance.ParameterList;
if (FamilyTreeViewModel.GetInstance.SelectedUnitSetting != null)
{
if (_internal_parameter_list.Count > 0)
{
for (int i = 0; i < _internal_parameter_list.Count; i++)
{
int startValue = i * 100 / _internal_parameter_list.Count;
unit_read_data_setting_Worker.ReportProgress(startValue);
// do stuff related to the index
// when progress_bar at 76 value, the loop stoppes and cotinue after a minute
}
}
}
}
}
private void _update_progress(object sender, ProgressChangedEventArgs e)
{
FamilyTreeViewModel.GetInstance.Unit_read_data_setting_progress_bar = e.ProgressPercentage;
}
private void Completed(object sender, RunWorkerCompletedEventArgs e)
{
// never gets here but there's no error
}
}

Windows Form in a Revit Addin

I have written quite a few different add-ins now but I keep struggling to get a windows form working on Revit. The program builds fine and I have the dll set up for Revit to access.
Here are the different sections of my code. The program is more extensive than what is seen but I believe that the problem is a reference issue or a problem with my ADDIN file. Maybe there is a different way I need to set up my ADDIN file since I have a windows form in it?? Let me know.
Here is a Dropbox folder with the screenshots in it.
Let me know if there is anything else you need to see. The error in Revit says it has to do with the FullName but I believe I put it in the ADDIN file correctly, and I did it the same as I had for other ADDINs.
Thank you for your help!
[TransactionAttribute(TransactionMode.Manual)]
[RegenerationAttribute(RegenerationOption.Manual)]
public class CicuitChecker : IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
//set document variable
Document document = commandData.Application.ActiveUIDocument.Document;
using (Transaction trans = new Transaction(document))
{
trans.Start("Circuit Checker");
UIApplication uiApp = commandData.Application;
Document doc = uiApp.ActiveUIDocument.Document;
//run through looped form in case of user not selecting needed fields, and store what family the user wants the program to check
Boolean messedUp = false;
Boolean All = false, lightF = false, recep = false, elecEquip = false, equipCon = false, junc = false, panels = false;
FilteredElementCollector collector = new FilteredElementCollector(doc), collector2 = new FilteredElementCollector(doc);
while (messedUp)
{
CircuitChecker.CircuitCheckerForm form = new CircuitChecker.CircuitCheckerForm();
form.ShowDialog();
//Get application and document objects
foreach (String item in form.getSelectionElementsLB())
{
if (item.Equals("All"))
{
All = true;
break;
}
else if (item.Equals("Lighting Fixtures"))
{
lightF = true;
}
else if (item.Equals("Recepticales"))
{
recep = true;
}
else if (item.Equals("Electrical Equipment (including Panels)"))
{
elecEquip = true;
}
else if (item.Equals("Junctions"))
{
junc = true;
}
else
{
messedUp = true;
TaskDialog.Show("Error", "At least one element must be selected.");
}
}
if (form.getSelectionPlaceLB().Equals("Entire Project"))
{
collector
= new FilteredElementCollector(doc)
.WhereElementIsNotElementType();
collector2
= new FilteredElementCollector(doc)
.WhereElementIsNotElementType();
}
else if (form.getSelectionPlaceLB().Equals("Elements in Current View"))
{
collector
= new FilteredElementCollector(doc, document.ActiveView.Id)
.WhereElementIsNotElementType();
collector2
= new FilteredElementCollector(doc, document.ActiveView.Id)
.WhereElementIsNotElementType();
}
else
{
messedUp = true;
TaskDialog.Show("Error", "A place must be selected.");
}
}
Color color = new Color(138, 43, 226); // RGB
OverrideGraphicSettings ogs = new OverrideGraphicSettings();
OverrideGraphicSettings ogsOriginal = new OverrideGraphicSettings();
ogs.SetProjectionLineColor(color);
int notCircuited = 0;
//ElementId symbolId = family
ElementCategoryFilter lightFilter = new ElementCategoryFilter(BuiltInCategory.OST_LightingFixtures);
ElementCategoryFilter recepFilter = new ElementCategoryFilter(BuiltInCategory.OST_ElectricalFixtures);
ElementCategoryFilter elecEquipFilter = new ElementCategoryFilter(BuiltInCategory.OST_ElectricalEquipment);
//ElementClassFilter filter = new ElementClassFilter(typeof("Junction Boxes - Load"));
//FamilyInstanceFilter juncFilter1 = new FamilyInstanceFilter(doc, );
LogicalOrFilter first = new LogicalOrFilter(lightFilter, recepFilter);
if (All)
{
collector.WherePasses(first);
IList<Element> allArr = collector.ToElements();
foreach (Element e in allArr)
{
int cirNum = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER).AsInteger();
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM).AsString();
if (!(IsNumeric(cirNum)) || (panel.Equals("")) || (panel.Equals("<unnamed>")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
collector2.WherePasses(elecEquipFilter);
IList<Element> elecEquipArr = collector.ToElements();
foreach (Element e in elecEquipArr)
{
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_PANEL_SUPPLY_FROM_PARAM).AsString();
if ((panel.Equals("")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
TaskDialog.Show("Circuit Checker", notCircuited + " lighting fixtures are not circuited in this view.");
trans.Commit();
}
if (!trans.HasEnded())
{
if (lightF)
{
collector.WherePasses(lightFilter);
IList<Element> lightArr = collector.ToElements();
foreach (Element e in lightArr)
{
int cirNum = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER).AsInteger();
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM).AsString();
if (!(IsNumeric(cirNum)) || (panel.Equals("")) || (panel.Equals("<unnamed>")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
}
if (recep)
{
collector.WherePasses(recepFilter);
IList<Element> recepArr = collector.ToElements();
foreach (Element e in recepArr)
{
int cirNum = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER).AsInteger();
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM).AsString();
if (!(IsNumeric(cirNum)) || (panel.Equals("")) || (panel.Equals("<unnamed>")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
}
if (elecEquip)
{
collector.WherePasses(elecEquipFilter);
IList<Element> elecEquipArr = collector.ToElements();
foreach (Element e in elecEquipArr)
{
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_PANEL_SUPPLY_FROM_PARAM).AsString();
if ((panel.Equals("")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
}
if (junc)
{
collector.WherePasses(recepFilter);
IList<Element> juncArr = collector.ToElements();
foreach (Element e in juncArr)
{
int cirNum = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER).AsInteger();
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM).AsString();
if (!(IsNumeric(cirNum)) || (panel.Equals("")) || (panel.Equals("<unnamed>")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
}
TaskDialog.Show("Circuit Checker", notCircuited + " lighting fixtures are not circuited in this view.");
trans.Commit();
}
}
return Result.Succeeded;
}
public static Boolean IsNumeric(Object Expression)
{
if (Expression == null || Expression is DateTime)
return false;
if (Expression is Int16 || Expression is Int32 || Expression is Int64 || Expression is Decimal || Expression is Single || Expression is Double || Expression is Boolean)
return true;
try
{
if (Expression is string)
Double.Parse(Expression as string);
else
Double.Parse(Expression.ToString());
return true;
}
catch { } // just dismiss errors but return false
return false;
}
}
This code is having the functionality in the 'main class.' I have since moved the functionality to the form class as konrad suggested but am still receiving the FullClassName error in Revit. Please Help!
The schedule data add-in provides a full Visual Studio solution demonstrating how to display a Windows form in a Revit add-in, including the generation of the Windows form on the fly:
http://thebuildingcoder.typepad.com/blog/2012/05/the-schedule-api-and-access-to-schedule-data.html
Here's how I usually set up my Windows Forms based External Commands. Remember that you have to create an External Command, and your addin manifest must point at this class. Then from this class you can launch the Form like so:
[Transaction(TransactionMode.Manual)]
public class SomeCommand : IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
// Get application and document objects
UIApplication uiApp = commandData.Application;
Document doc = uiApp.ActiveUIDocument.Document;
UIDocument uidoc = uiApp.ActiveUIDocument;
try
{
SomeNamespace.SomeForm form = new SomeNamespace.SomeForm(doc);
form.ShowDialog();
return Result.Succeeded;
}
// Catch any exceptions and display them
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
return Result.Cancelled;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
So I have a Form class that I instantiate from my ExternalCommand and pass Document to its constructor. That way I have access to document when I am interacting with the form later. I wire up all functionality in code behind of the Form.
Agree, the OP's question is why doesn't the addin work...
From looking at the images, it seems like the issue is that Revit is not properly finding the full class name of the command.
It's a little unusual that you don't have your command class wrapped in a namespace (your form class is, for example).
I would recommend wrapping it in a namespace like "circuitchecker" - like your form class.
Then the "full name" in the addin file would become "circuitchecker.circuitchecker"
(the namespace.classname) - this helps Revit distinguish different classes that might have the same name.
side note: I don't believe that putting a URL into the Image/LargeImage fields in the addin will work - but not positive.

How to get all the textBoxes in the UserControl added into GridView

On the Page, I add UserControl into GridView dynamically. So, each UserControl can contain different kind of controls ( TextBox, CheckBox, Radio Button)
say , the name of UserControl is : UserForm.
problem :
How to get a collection of control using VisualTreeHelper and check if textBox is empty.
I found a code similiar to this problem and modified it but not working.
I dont know what this means and if this is required?
list.AddRange(AllTextBoxes(child))
Should I use MyList.Select() or MyList.Where() ?
void FindTextBoxes()
{
List <TextBox> MyList = AllTextBoxes(UserForm);
var count = MyList.Where(x= > if(string.IsEmptyOrNull(x.Text));
}
List <TextBox> AllTextBoxes(DependencyObject parent)
{
var list = new List <TextBox>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (child is TextBox)
list.Add(child as TextBox);
list.AddRange(AllTextBoxes(child));
}
return list;
}
Here's what I use.
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var textBoxes = AllChildren(MyGridView).Where(x => x is TextBox);
}
public IEnumerable<Control> AllChildren(DependencyObject parent)
{
for (int index = 0; index < VisualTreeHelper.GetChildrenCount(parent); index++)
{
var child = VisualTreeHelper.GetChild(parent, index);
if (child is Control)
yield return child as Control;
foreach (var item in AllChildren(child))
yield return item;
}
}
Best of luck!

How to avoid java.util.NoSuchElementException

The code below is giving me the error java.util.NoSuchElementException right after I Ctrl+Z
to indicate that the user input is complete. By the looks of it seems as if it does not know how to just end one method without messing with the other scanner object.
I try the hasNext method and I ended up with an infinite loop, either way is not working. As a requirement for this assignment I need to be able to tell the user to use Ctrl+Z or D depending on the operating system. Also I need to be able to read from a text file and save the final tree to a text file please help.
/* sample input:
CSCI3320
project
personal
1 HW1
1 HW2
1 2 MSS.java
2 p1.java
*/
import java.util.Scanner;
import java.util.StringTokenizer;
public class Directory {
private static TreeNode root = new TreeNode("/", null, null);
public static void main(String[] args) {
userMenu();
System.out.println("The directory is displayed as follows:");
root.listAll(0);
}
private static void userMenu(){ //Displays users menu
Scanner userInput = new Scanner(System.in);//Scanner option
int option = 0;
do{ //I believe the problem is here since I am not using userInput.Next()
System.out.println("\n 1. add files from user inputs ");
System.out.println("\n 2. display the whole directory ");
System.out.println("\n 3. display the size of directory ");
System.out.println("\n 0. exit");
System.out.println("\n Please give a selection [0-3]: ");
option = userInput.nextInt();
switch(option){
case 1: addFileFromUser();
break;
case 2: System.out.println("The directory is displayed as follows:");
root.listAll(0);
break;
case 3: System.out.printf("The size of the directory is %d.\n", root.size());
break;
default:
break;
}
}while( option !=0);
userInput.close();
}
private static void addFileFromUser() {
System.out.println("To terminate inp1ut, type the correct end-of-file indicator ");
System.out.println("when you are prompted to enter input.");
System.out.println("On UNIX/Linux/Mac OS X type <ctrl> d");
System.out.println("On Windows type <ctrl> z");
Scanner input = new Scanner(System.in);
while (input.hasNext()) { //hasNext being used Crtl Z is required to break
addFileIntoDirectory(input); // out of the loop.
}
input.close();
}
private static void addFileIntoDirectory(Scanner input) {
String line = input.nextLine();
if (line.trim().equals("")) return;
StringTokenizer tokens = new StringTokenizer(line);
int n = tokens.countTokens() - 1;
TreeNode p = root;
while (n > 0 && p.isDirectory()) {
int a = Integer.valueOf( tokens.nextToken() );
p = p.getFirstChild();
while (a > 1 && p != null) {
p = p.getNextSibling();
a--;
}
n--;
}
String name = tokens.nextToken();
TreeNode newNode = new TreeNode(name, null, null);
if (p.getFirstChild() == null) {
p.setFirstChild(newNode);
}
else {
p = p.getFirstChild();
while (p.getNextSibling() != null) {
p = p.getNextSibling();
}
p.setNextSibling(newNode);
}
}
private static class TreeNode {
private String element;
private TreeNode firstChild;
private TreeNode nextSibling;
public TreeNode(String e, TreeNode f, TreeNode s) {
setElement(e);
setFirstChild(f);
setNextSibling(s);
}
public void listAll(int i) {
for (int k = 0; k < i; k++) {
System.out.print('\t');
}
System.out.println(getElement());
if (isDirectory()) {
TreeNode t = getFirstChild();
while (t != null) {
t.listAll(i+1);
t = t.getNextSibling();
}
}
}
public int size() {
int s = 1;
if (isDirectory()) {
TreeNode t = getFirstChild();
while (t != null) {
s += t.size();
t = t.getNextSibling();
}
}
return s;
}
public void setElement(String e) {
element = e;
}
public String getElement() {
return element;
}
public boolean isDirectory() {
return getFirstChild() != null;
}
public void setFirstChild(TreeNode f) {
firstChild = f;
}
public TreeNode getFirstChild() {
return firstChild;
}
public void setNextSibling(TreeNode s) {
nextSibling = s;
}
public TreeNode getNextSibling() {
return nextSibling;
}
}
}
Exception Details:
/*Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:907)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at Directory.userMenu(Directory.java:36)
at Directory.main(Directory.java:21)*/
Your problem is this line:
option = userInput.nextInt(); //line 24
If you read the Javadoc, you will find that the nextInt() method can throw a NoSuchElementException if the input is exhausted. In other words, there is no next integer to get. Why is this happening in your code? Because you this line is in a loop once that first iteration completes (on the outer while loop) your initial input selection has been consumed. Since this is a homework, I am not going to write the code. But, if you remove the loop, you know this works at least once. Once you try to loop, it breaks. So I will give you these hints:
Change the do/while to a while loop.
Prompt the user once outside the loop.
Recreate the prompt and recapture the user input inside the loop.
For example, the code below can be used for the basis of your outer loop.
import java.util.Scanner;
public class GuessNumberGame {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Guess the secret number: (Hint: the secret number is 1)");
int guess = input.nextInt();
while (guess != 1) {
System.out.println("Wrong guess. Try again: ");
guess = input.nextInt();
}
System.out.println("Success");
input.close();
}
}
The reason why this works is because I don't reuse the same, exhausted, scanner input object to get the next integer. In your example, the initial input is inside the loop. The second time around, that input has already been consumed. Follow this pattern and you should be able to complete your assignment.

How to create multiple checkbox in canvas

I get trouble when I try to create a check box in canvas.
My checkbox works well but I don't know how to store value of each item, that mean when user check row 1 , and then they move to another row check box still check row 1, and when user check row 1 and 2 and move to another row, check box will check row 1 and 2.
But I can't find out solution for this problem
modify your code to use selectTodelete as boolean array instead of int, about like shown below
// ...initialization of DataList
boolean[] selectTodelete = new boolean[2]; // instead of int
{ selectTodelete[0] = selectTodelete[1] = false; } // init array
Command editCommand, backCommand,selectCmd, unselectCmd,selectAll;
//...
protected void paint(Graphics g) {
//...
for(int i =0 ; i<countRow; i++ ){
//draw background
//...
if(selectTodelete[i]){ // was selectTodelete == 1
//draw select dot at location for row 'i'
//...
}
// remove: you don't need that anymore: if(selectTodelete == 2) {
//draw select dot...
//}
// draw a checkbox before each item
// ...
}
}
public void commandAction(Command c, Displayable d) {
//...
if(c == selectCmd){
selectTodelete[selectedItem] = true;
}
if(c== unselectCmd){
selectTodelete[selectedItem] = false;
}
if(c == selectAll){
selectTodelete[0] = selectTodelete[1] = true;
}
repaint();
}
//...
}
update - answer to question in comments
I want to get RCID fit to checked it mean when row was checked I can get this id and when I use delete command it will delete all rows were checked
For that, you can expose selectTodelete for use outside of its class with getter, or, better yet, with method like below...
boolean isSelected(int elementNum) {
return elementNum >= 0 && elementNum < selectTodelete.length
&& selectTodelete[elementNum];
} // modelled after javax.microedition.lcdui.Choice.isSelected
...information exposed like that can be further used anywhere when you need it to deal with RCID, like eg in method below:
Vector useSelection(DataList dataList, DataStore[][] ds) {
Vector result = new Vector();
int count = ds.length;
for(int i = 0; i < count; i++ ) {
if (!dataList.isSelected(i)) {
continue; // skip non selected
}
System.out.println("RCID selected: [" + ds[i][5].cellText + "]");
result.addElement(ds[i][5]);
}
return result;
}

Resources