I'm attempting to iterate through all the textboxes in my WPF window to see if they are empty, and if they are, the method should set a bool to true.
private void checkTextBoxes(DependencyObject obj)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
if (obj is TextBox && ((TextBox)obj).Text == null)
{
isTextBoxEmpty = true;
}
}
}
isTextBoxEmpty is my bool that has been defined outside of the method. I call the method using:
checkTextBoxes(this);
But the bool always returns false no matter what I do, even if all the text boxes are empty.
Try to change this :
((TextBox)obj).Text == null)
To this :
(String.IsNullOrEmpty((TextBox)obj).Text))
The result you got possibly because TextBox's Text is never null, it is empty string ("") by default, thats what I think, just possibly.
Outside of any syntax errors this should give you the result you expect; This only returns true if ALL textboxes are blank
private void checkTextBoxes(DependencyObject obj)
{
var trueforall = true;
var atleastone = false;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
if (obj is TextBox)
{
if(!atleastone){ atleastone = true;}
trueforall &= string.IsNullOrWhiteSpace(((TextBox)obj).Text);
if (!trueforall) { break; }
}
}
isTextBoxEmpty = trueforall && atleastone;
}
Related
Inside OnSelectionChange() inside a EditorWindow script type:
I want to check if the selected object transform is identical to one of the transforms in test. selections is List test is array
First I want to check if one of the transforms data in text is identical to the selected object transform data. Then In the editor in the hierarchy I'm deleting the object and now it is null. Now selected is null. Now I want to check that if the object is null but also was identical in the first check then set a flag to true and if it's not null or not identical set a flag to false.
private void OnSelectionChange()
{
selectionChanged = true;
var selections = Selection.objects.OfType<GameObject>().ToList();
var test = TransformSaver.LoadTransforms();
if (selections.Count > 0)
tempsel = selections;
if (tempsel.Count > 0)
{
for (int x = 0; x < tempsel.Count; x++)
{
for (int i = 0; i < test.Length; i++)
{
var selected = tempsel[x];
if (selected.transform.parent == test[i].parent &&
selected.transform.name == test[i].name &&
selected.transform.localPosition == test[i].pos &&
selected.transform.localRotation == test[i].rot &&
selected.transform.localScale == test[i].scale)
{
hasLoaded = true;
}
}
}
for (int y = 0; y < selections.Count; y++)
{
if (selections[y] == null && hasLoaded == true)
{
hasLoaded = false;
}
}
}
}
The next step is to use the flag to decide if to enable true or false a button inside OnGUI:
private void Load()
{
if (selectionChanged)
{
if (hasLoaded == true)
{
GUI.enabled = true;
}
else
{
GUI.enabled = false;
}
}
if (GUILayout.Button("Load"))
{
TransformSaver.LoadTransform();
hasLoaded = false;
}
}
But so far no success.
The main goal logic rules as I see it, Maybe they should be others but this is how I explain what I want to do:
To compare the Transforms data between the selections and test.
Set a flag to true if the data is identify in one or more of the selections objects against the test array.
To check if the one or more of the selections objects are null and if they are null now to check if they were identify in the first check (1).
If both selected objects one or more and the test Transforms data one or more are identify and also null only then set another flag to true.
Use the new flag if it's true or false to decide if to enable true/false the button "Load"
Last the TransformSaver class that test is getting the Transforms data array from: (I have another button "Save" that save a selection of objects and then I use LoadTransforms() to return the array of data of the saved Transforms from the JSON file)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine.SceneManagement;
public static class TransformSaver
{
[System.Serializable]
public class Transform
{
public string sceneName;
public string name;
public UnityEngine.Transform parent;
public Vector3 pos;
public Quaternion rot;
public Vector3 scale;
}
//Save Transform
public static void SaveTransform(UnityEngine.Transform[] tranformToSave)
{
Transform[] trnfrm = new Transform[tranformToSave.Length];
for (int i = 0; i < trnfrm.Length; i++)
{
trnfrm[i] = new Transform();
trnfrm[i].sceneName = tranformToSave[i].gameObject.scene.name;
trnfrm[i].name = tranformToSave[i].name;
trnfrm[i].parent = tranformToSave[i].parent;
trnfrm[i].pos = tranformToSave[i].localPosition;
trnfrm[i].rot = tranformToSave[i].localRotation;
trnfrm[i].scale = tranformToSave[i].localScale;
}
string jsonTransform = JsonHelper.ToJson(trnfrm, true);
//PlayerPrefs.SetString("transform", jsonTransform);
File.WriteAllText(#"d:\json\json.txt", jsonTransform);
}
public static Transform[] LoadTransforms()
{
string jsonTransform = File.ReadAllText(#"d:\json\json.txt");
if (jsonTransform == null)
{
return null;
}
Transform[] savedTransforms = JsonHelper.FromJson<Transform>(jsonTransform);
return savedTransforms;
}
}
I have a BindingList called bList that is getting utilized in a GUI.
public BindingList<SomeList> bList = new BindingList<SomeList>();
What I'm trying to do is change the RowStyle with an event by checking a property in bList. Let's say in bList I have 6 objects which have multiple properties. One of the properties in bList I have is called isValid, which is a bool, if that's set to false I turn that row red, else the row just stays the default color.
I was able to get all rows turning red if they are >= 0. How can I iterate over bList to find the property isValid for each object in blist?
private void gridView_RowStyle(object sender, RowStyleIEventArgs e)
{
bool isValid = class.bList[0].isValid;
if (e.RowHandle >= 0)
{
if (isValid == false)
{
e.Appearance.BackColor = Color.Red;
}
}
}
You should use reflection to get the property value of your object. Here is a sample function that will work for a generic BindingList.
Use:
for (int i = 0; i < myList.Count; i++)
{
object val = null;
TryGetPropertyValue<SomeType>(myList, i, "isValid", out val);
bool isValid = Convert.ToBoolean(val);
// Process logic for isValid value
}
Method:
static private bool TryGetPropertyValue<T>(BindingList<T> bindingList, int classIndex, string propertyName, out object val)
where T : class
{
try
{
Type type = typeof(T);
PropertyInfo propertyInfo = type.GetProperty(propertyName);
val = propertyInfo.GetValue(bindingList[classIndex], null);
return val != null; // return true if val is not null and false if it is
}
catch (Exception ex)
{
// do something with the exception
val = null;
return false;
}
}
In order to change the color of a row based on a property value, you should add that property as a hidden column and then use that cell's value to set the style.
See the following:
How to change a row style based on a column value
For your problem:
private void gridView_RowCellStyle(object sender, DevExpress.XtraGrid.Views.Grid.RowCellStyleEventArgs e)
{
string valid = gridView.GetRowCellValue(e.RowHandle, "isValid").ToString().ToLower();
if(valid == "true")
e.Appearance.BackColor = Color.Red;
}
To add a hidden column:
Hide Column in GridView but still grab the values
I'm now able to iterate over the BindingList bList because I had some other issues with inheritance trying to figure out what type for the iterator.
foreach (SomeType item in bList)
{
if (e.RowHandle >= 0)
{
if (instance.isValid == false)
{
e.Appearance.BackColor = Color.Red;
}
else
{
e.Appearance.BackColor = Color.White;
}
}
}
How come all the rows are still turning red even though I'm finding which object with the property isValid is returning false.
here is my code
public bool limitOutput()
{
double lowerLeftPointX = m_mapControl.CurrentExtent.LowerLeftPoint.X;
double lowerLeftPointY = m_mapControl.CurrentExtent.LowerLeftPoint.Y;
double upperRightPointX = m_mapControl.CurrentExtent.UpperRightPoint.X;
double upperRightPointY = m_mapControl.CurrentExtent.UpperRightPoint.Y;
for(int i = locationElements.Count - 1; i >= 0; i--)
{
if (Double.Parse(locationElements[i]["GEOMETRY_X"].InnerText) < lowerLeftPointX || Double.Parse(locationElements[i]["GEOMETRY_X"].InnerText) > upperRightPointX || Double.Parse(locationElements[i]["GEOMETRY_Y"].InnerText) < lowerLeftPointY || Double.Parse(locationElements[i]["GEOMETRY_Y"].InnerText) > upperRightPointY)
{
locationElements[i].ParentNode.RemoveChild(locationElements[i]);
}
}
if (locationElements.Count == 0)
{
PearMessageBox.Show(PearMessageBox.mBoxType.simpleNotification, "No results found in specified area");
return false;
}
return true;
}
I am trying to delete all the nodes which are not within the boundary I have set. The delete line is executed but does not actually delete as when I count locationElements it is still the same value before the method is executed.
Any ideas what is wrong with the code
The problem is due to the fact that RemoveChild() removed the element from the source XmlDocument, but not from the pre-populated XmlNodeList. So you need to execute again the code that was used to pre-populate locationElements variable, something like this :
//assume that GetLocationElements() is a method...
//...containing the same logic you used to populate locationElements variable
var updatedLocationElements = GetLocationElements();
if (updatedLocationElements.Count == 0)
{
PearMessageBox.Show(PearMessageBox.mBoxType.simpleNotification, "No results found in specified area");
return false;
}
return true;
I have a List of MyClass and in the main page I have 10 controls which will display the information about that list of Items. What I want is to check the count of the items in the List and then make the excess controls invisible. Now I'm using this code but is there an easier way of doing this?
if (myList.Count > 0)
{
Control1.MyClassInfo = myList[0];
if (myList.Count > 1)
{
Control2.MyClassInfo = myList[1];
if (myList.Count > 2)
{
// and like that till 10
}
else
{
Control3.Visible = false;
Control4.Visible = false;
// till 10
}
}
else
{
Control2.Visible = false;
Control3.Visible = false;
// till 10
}
}
else
{
Control1.Visible = false;
Control2.Visible = false;
Control3.Visible = false;
// and then till 10
}
Well, just add your controls in a list (ordered).
Something like that
var controlList = new List<Control>{ Control1, Control2, Control3 /*etc*/};
var count = myList.Count;
for (var i = 0; i < controlList.Count; i++) {
controlList[i].Visible = count > i;
}
You could create a list of your controls
List<Control> MyControls = new List<Control>{Control1, Control2,..,Control10};
and then
foreach(var C in MyControls)
C.Visible=false;
for(int i=0; i<myList.Count; i++)
C[i].Visible=true;
EDIT: for the more advanced coders here, this technique is called the Composite Pattern.
Basically, that's it. But you can improve on that basic concept in two ways:
1) use a collection
List<Control> _controls1to10;
Put your controls into that collection and write a method like this:
private void setVisibility(List<Control> _controls, bool visible)
{
foreach (Control c in _controls1to10)
{
c.Visible = visible;
}
}
This will make things easier.
2) use boolean expressions instead of nested ifs, like this:
bool hasElements = myList.Count > 0;
bool hasMoreThan1 = myList.Count > 1;
// ... and so on
This means that you have master switches at the top and use them in the following code. This is a fantasy example to clear the concept but does not apply to your code:
bool isEditable = User.LoggedIn && SystemState.Maintenance == false && item.Count > 0;
editButton.Visible = isEditable;
dropList.Visible = !isEditable;
I wrote the following method to load a list box with values that have not been loaded already but I am getting an Object reference not set to an instance of an object exception when assigning the following. Any information would be helpful. Thanks.
lbxCabinetName.Items.Add(cabinetsCurrentNotUsed[i].ToString());
// Defined outside a method
List<string> cabinetsCurrentNotUsed;
// Set value in the constructor
cabinetsCurrentNotUsed = new List<string>();
Here is the whole procedure.
private void selectCabinetToAdd()
{
// Loop through all server and form cabinet types to see if there are matches
for (int x = 0; x < opticalFile.serverCabinetNames.Count; x++)
{
bool cabinetExists = false;
for (int i = 0; i < opticalFile.CabinetValues.Count; i++)
{
if (opticalFile.serverCabinetNames[x].ToString() == opticalFile.CabinetValues[i].ToString())
{
cabinetExists = true;
}
}
// Add cabinets not used to cabinetsCurrentNotUsed List
if (!cabinetExists)
{
cabinetsCurrentNotUsed.Add(opticalFile.serverCabinetNames[x].ToString());
}
}
// Send cabinetsCurrentNotUsed List to list box
for (int i = 0; i < cabinetsCurrentNotUsed.Count; i++)
{
lbxCabinetName.Items.Add(cabinetsCurrentNotUsed[i].ToString());
}
}
You are trying to add a null to the listbox.
Insted of
for (int i = 0; i < cabinetsCurrentNotUsed.Count; i++)
{
lbxCabinetName.Items.Add(cabinetsCurrentNotUsed[i].ToString());
}
use
foreach (string s in cabinetsCurrentNotUsed)
{
if(s != null)
lbxCabinetName.Items.Add(s);
}
NOTE
This part is not relavant to the question. But in your inner for loop after setting cabinetExists = true; you can break out of the inner loop (if atleast one condition is met you can make sure the cabinetExists is true. you don't have to check for the rest of the items in the inner loop)
EDIT
private void selectCabinetToAdd()
{
foreach (string sc in serverCabinetNames)
{
bool cabinetExists = false;
foreach (string cv in CabinetValues)
{
if (sc == cv)
{
cabinetExists = true;
break;
}
}
if (!cabinetExists)
{
cabinetsCurrentNotUsed.Add(sc);
}
}
foreach (string ccnu in cabinetsCurrentNotUsed)
{
if (ccnu != null)
lbxCabinetName.Items.Add(ccnu);
}
}
Also if your listBox can be null, make sure you check that first before populating the listbox.
if(lbxCabinetName != null)
{
selectCabinetToAdd();
}
EDIT 2
Dynamically adding control
ListBox lbxCabinetName = new ListBox();
lbxCabinetName.Location = new System.Drawing.Point(10, 55);
lbxCabinetName.Size = new System.Drawing.Size(130, 95);
this.Controls.Add(lbxCabinetName);
Strings are nullable so at some point you must be doing something similar to:
cabinetsCurrentNotUsed.Add(null);
Either that or as dbaseman said it is possible lbxCabinetName is null but I'm betting that isn't the case.
As an aside, it's not really a problem but if you're using a generic list of strings the ToString() call isn't necessary. You can just do this:
lbxCabinetName.Items.Add(cabinetsCurrentNotUsed[i]);