I am using FlaUI to automate my WPF app. I have a datagrid control from DevExpress. I want to access any individual row and all the columns of that row and edit it using FlaUI. The DevExpress forum has the following sample available but this is for UIA library.How can I rewrite this using FlaUI libraries?
AutomationElement gridElem = AutomationElement.RootElement.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.LocalizedControlTypeProperty, "datagrid"));
GridPattern gridPattern = (GridPattern)gridElem.GetCurrentPattern(GridPattern.Pattern);
int rowCount = gridPattern.Current.RowCount;
List<object> values = new List<object>();
for (int i = 0; i < rowCount; i++) {
AutomationElement item = gridPattern.GetItem(i, 0);
ValuePattern valuePattern = (ValuePattern)item.GetCurrentPattern(ValuePattern.Pattern);
values.Add(valuePattern.Current.Value);
Very new to FlaUI & automation.
Finally with some help from DevExpress Support, I was able to achieve my intentions. Here is the piece of code that works well :)
public void CreateNewViewGrid(Grid grid)
{
var pattern = grid.Patterns.Grid;
var rowCount = pattern.Pattern.RowCount;
var colCount = pattern.Pattern.ColumnCount;
var values = new List<object>();
List<string> columnNames = new List<string>();
columnNames.Add("Vessel Id");
columnNames.Add("Voyage Id");
columnNames.Add("Load Date");
columnNames.Add("Dis Date");
columnNames.Add("Vessel Name");
columnNames.Add("Status");
for (int i = 0; i < rowCount; i++)
{
var item = pattern.Pattern.GetItem(i, 0);
var item2 = pattern.Pattern.GetItem(i, 1);
var value = (item2.Patterns.Value.Pattern.Value).ToString();
values.Add((value));
foreach (var data in columnNames)
{
if (value == data)
{
var itemStatus = item.AsGridCell();
itemStatus.Click();
}
}
}
//Console.WriteLine(string.Join(", ", values));
//return values;
}
before this, finding element using FlaUI is necessary
Grid(reference from FlaUI.Core.AutomationElements)
private Grid grid=>windows.FindFirstDescendant(cf=>cf.ByAutomationID("dataGrid").AsGrid();
I am new to WPF, I am creating a datagrid dynamically by taking the NoOfRows & NoOfColumns as input. But the datagrid is not becoming Editable as I am not passing any Item source.
Is There any way of making the datagrid editable while not giving any Item source?
My Code is Like this (I have taken checkbox columns as datagrid column, I want to check the checkboxes):
var row = Convert.ToInt32(TbxLevels.Text);
var column = Convert.ToInt32(TbxPositions.Text);
Dgrid.Columns.Clear();
Dgrid.Items.Clear();
for (int i = 0; i < column; i++)
{
var c = new DataGridCheckBoxColumn();
c.Header = column;
Dgrid.Columns.Add(c);
}
for (int i = 0; i < row; i++)
{
Dgrid.Items.Add(i);
}
I have data which I import from textfiles, transfer to an sqlite db, then transfer that into LISTS. Now I want to show these lists to the user in a LISTVIEW. Each column should contain a list.
Below, the contents of the second column are perfectly fine. But, the 3rd and the fourth column should be vertically filled with the items that correspond to their color values.
I.e from the code below, I want to populate the 3rd and 4th column with the MaxLen list and PercentPopList list. (Yes I know that I skipped a column, but i'll fix that later)
I'm new to programming and I cant figure out how to make that work.
ListViewItem lvi = new ListViewItem();
foreach (object o in SeqIrregularities)
{
lvi.SubItems.Add(o.ToString());
listView1.Items.Add(lvi);//Adds a new row
lvi = new ListViewItem();
}
listView1.Items.Add(lvi);//Adds a new row
lvi = new ListViewItem();
foreach (object a in MaxLen)
{
lvi.SubItems.Add(a.ToString());
}
listView1.Items.Add(lvi);//Adds a new row
lvi = new ListViewItem();
foreach (object b in PercentPopList)
{
lvi.SubItems.Add(b.ToString());
}
listView1.Items.Add(lvi);//Adds a new row
Your data is in the wrong format. Simplifying, you seem to have data like this:
var firstColumnValues = new List<int>();
var secondColumnValues = new List<int>();
var thirdColumnValues = new List<int>();
While each individual list may make sense on its own, they currently don't relate to each other in any meaningful way. What you need to do is think about the format of the object which represents one "record" of data. Still overly-simplified, something like this:
class RecordOfValues
{
public int FirstValue { get; set; }
public int SecondValue { get; set; }
public int ThirdValue { get; set; }
}
Then you'd just have one list of them:
var listOfRecords = new List<RecordOfValues>();
At this point you would have a list of "records" to bind to the ListView.
As far as I understand that you don't have too much experience and cannot easily come up with an algorithm accounting for the suggested modifications; here you have a sample code showing how to extend your code to populate three different columns from 3 different lists:
List<string> SeqIrregularities = new List<string>();
SeqIrregularities.Add("1");
SeqIrregularities.Add("2");
SeqIrregularities.Add("3");
List<string> MaxLen = new List<string>();
MaxLen.Add("4");
MaxLen.Add("5");
MaxLen.Add("6");
List<string> PercentPopLis = new List<string>();
PercentPopLis.Add("7");
PercentPopLis.Add("8");
PercentPopLis.Add("9");
PercentPopLis.Add("10");
PercentPopLis.Add("11");
int totItems = SeqIrregularities.Count - 1;
if (MaxLen.Count - 1 > totItems) totItems = MaxLen.Count - 1;
if (PercentPopLis.Count - 1 > totItems) totItems = PercentPopLis.Count - 1;
for (int i = 0; i <= totItems; i++)
{
ListViewItem lvi = new ListViewItem();
string item1 = "";
string item2 = "";
string item3 = "";
if (SeqIrregularities.Count - 1 >= i) item1 = SeqIrregularities[i];
if (MaxLen.Count - 1 >= i) item2 = MaxLen[i];
if (PercentPopLis.Count - 1 >= i) item3 = PercentPopLis[i];
lvi.SubItems.Add(item1);
lvi.SubItems.Add(item2);
lvi.SubItems.Add(item3);
listView1.Items.Add(lvi);
}
Hi I neeed to do this one in a loop, but I don't have any idea how to do. I can't do this by just simply incrementing it.
CheckBox[] checkboxarray;
checkboxarray = new CheckBox[] {
txtChckBx0, txtChckBx1, txtChckBx2, txtChckBx3, txtChckBx4, txtChckBx5,
txtChckBx6, txtChckBx7, txtChckBx8, txtChckBx9, txtChckBx10, txtChckBx11,
txtChckBx12, txtChckBx13, txtChckBx14, txtChckBx15, txtChckBx16, txtChckBx17,
txtChckBx18, txtChckBx19, txtChckBx20, txtChckBx21, txtChckBx22, txtChckBx23,
txtChckBx24, txtChckBx25, txtChckBx26, txtChckBx27, txtChckBx28, txtChckBx29,
txtChckBx30, txtChckBx31, txtChckBx32, txtChckBx33, txtChckBx34, txtChckBx35,
txtChckBx36, txtChckBx37, txtChckBx38, txtChckBx39, txtChckBx40, txtChckBx41,
txtChckBx42, txtChckBx43, txtChckBx44, txtChckBx45, txtChckBx46, txtChckBx47,
txtChckBx48, txtChckBx49, txtChckBx50, txtChckBx51, txtChckBx52, txtChckBx53,
txtChckBx54, txtChckBx55, txtChckBx56, txtChckBx57, txtChckBx58, txtChckBx59,
txtChckBx60, txtChckBx61, txtChckBx62, txtChckBx63, txtChckBx64, txtChckBx65,
txtChckBx66, txtChckBx67, txtChckBx68, txtChckBx69, txtChckBx70, txtChckBx71,
txtChckBx72, txtChckBx73, txtChckBx74, txtChckBx75, txtChckBx76, txtChckBx77,
txtChckBx78, txtChckBx79, txtChckBx80
};
If you know that the checkboxes are all on a form:
var list = new List<CheckBox>();
foreach(var control in this.Controls)
{
var checkBox = control as CheckBox;
if(checkBox != null)
{
list.Add(checkBox);
}
}
var checkBoxArray = list.ToArray();
If you don't know where the controls are then you will have to search for them.
BTW: The code above uses WinForms. If you are using WPF, Silverlight, Metro,... the container will be named differently.
You can't do new and then
checkboxarray = new CheckBox[] { txtChckBx0, ....}
it's two different ways to define an array.
you need to do:
CheckBox[] checkboxarray = { txtChckBx0, ....};
If you want it to work.
Good luck.
In WinForm
List<CheckBox> checkBox = new List<CheckBox>();
// Adding checkboxes for testing...
for (int i = 0; i <= 80; i++)
{
var cbox = new CheckBox();
cbox.Name = "txtChckBx"+ i.ToString();
checkBox.Add(cbox);
Controls.Add(cbox);
}
List<CheckBox> checkBoxfound = new List<CheckBox>();
// loop though all the controls
foreach (var item in Controls)
{
// filter for checkboxes and name should start with "txtChckBx"
if (item is CheckBox && ((CheckBox)item).Name.StartsWith("txtChckBx", StringComparison.OrdinalIgnoreCase))
{
checkBoxfound.Add((CheckBox)item);
}
}
for (int i = 0; i < listView1.Items.Count; i++)
{
if (listView1.Items[i].Selected)
{
listView1.Items[i].Remove();
}
}
This function simply deletes the selected item in listview.. but i want to cut it and paste it somewhere else.
It sounds like you want to remove the selected listitems and move them to another listview.
ListView sourceListView = new ListView();
ListView destListView = new ListView();
var selected = sourceListView.Items
.Cast<ListViewItem>()
.Where(x => x.Selected)
.ToList();
foreach (var item in selected)
{
sourceListView.Items.Remove(item);
destListView.Items.Add(item);
}