I have a telerik control (Telerik.WinControls.UI.RadToggleSwitch) which is used to toggle between state 1 and state 2 with "Click and drag (left or right)" to make the toggle effect. I want to do a hand-coded UI test to select a state and proceed further. I need a class to call that control(i assumed it is WinClient).
I need the proper code to perform toggle action. Thanks in advance.
You may handcode your Coded UI Tests but handcoding your UIControls is really troublesome to do as you can never be sure that the Control you added is actually found and everything you did is correct.
A better alternative is to use the UIMap to manually add your controls via the Coded UI Test Builder. It also saves a lot of time.
When the Coded UI Test Builder is open you can hover with your mouse over a control and type "Control+I" to get info on that specific control. If you now click on the << on the infobox that opens you see your UIMap with the control you did "Control+I" over on the left added. But the control is not added yet permanently. From here you can add it permanently by clicking on the square with the green plus sign.
Add Button Icon
Alternatively the easy way is to hover over a control and push "Control+Shift+I".
See also: https://learn.microsoft.com/en-us/visualstudio/test/use-ui-automation-to-test-your-code
After adding the specific control to the UIMap you may use it by referecing to the UIMap. When coding in the *.cs file of the UIMaps you can reference to it by the "this" statement.
For example:
this.UIWindow.UITitleBar.UICloseButton;
When you want to use it outside of the files of the UIMap you have to create an object of the class of the UIMap and then can use it like above by repacing "this" with the object reference.
For example:
MyUIMapClass uIMapObject = new MyUIMapClass();
uIMapObject.UIWindow.UITitleBar.UICloseButton;
If the file you are coding in is not in the same namespace you have to add a using statement for the namespace of the UIMap (the namespace is defined at the begining of each file in the UIMap).
So for your control I think what you need is Mouse.StartDragging() and Mouse.StopDragging().
public static void StartDragging(UITestControl control);
public static void StopDragging(UITestControl control, int moveByX, int moveByY);
So a dragging towards left would be:
Mouse.StartDragging(UIYourControl)
Mouse.StopDragging(UIYourControl, -20, 0);
And toward right:
Mouse.StartDragging(UIYourControl)
Mouse.StopDragging(UIYourControl, 20, 0);
You should test a bit with the amount you need to drag in each direction for it to register as dragging but I think -20 and 20 should be fine.
I hope I helped a bit. :)
Related
For those who are very familiar with C# or VB.NET using the UserControl component in the .NET Framework (which is the hottest framework in my opinion), you were used to adding several buttons that preview different user controls as follows:
1) First you would prepare an appropriate user interface (contains 3 buttons and a single panel on the right area to view each user control after clicking one of the added buttons).
2) Adding 3 user controls from the solution explorer...
3) Inserting the content on each user control...
4) Implementing code for the 3 buttons on the frmMain.cs as the following (for this implementation we will be implementing the "Welcome" button carrying the object name as welcomeBtn, and the rest will have identical code but different user control names instead):
private void welcomeBtn_Click(object sender, EventArgs e)
{
//Clear up everything from the panel if any item exist(s)...
mainPanel.Controls.Clear();
//Create a new instance of a user control for the button...
UserControl1_Welcome welcome = new UserControl1_Welcome();
//Show up the created instance of the user control
mainPanel.Controls.Add(welcome);
}
5) Finally, the program will end up initially like this when running:
http://i.stack.imgur.com/OENwG.png
** Usage of the program **
When you click on the "Welcome" button for example, the result should be expected to be like this:
http://i.stack.imgur.com/iCyo3.png
... and when you click on a different button, lets say "License Agreement" button, you would expect to see something other than your current selection.
MAIN QUESTION
How can we bring the simplicity of Windows Forms in QT CREATOR by applying the "QDockWidget"?
I have tried inserting the QDockWidget component with no problems, but when I try to do the equivalent .NET code for adding the QWidget inside the QDockWidget:
ui->dockWidget->setWidget(myWidget);
which I think is equivalent to this line of code in C#.NET (correct me if I'm wrong here):
ui.Controls.Add(myWidget);
After using this code, my program won't crash nor shows anything running...
P.S. I'm sorry for linking the images, I don't have 10 reputation for making them show up...
What I want is to have a program that does the same thing with the C# example (showing a user control based on the click of a button).
If you want to show a particular widget based on a button click, I suggest to use a QStackedWidget
A simple example would be like this:
// In the constructor of your CustomWidget
// Create your buttons
QPushButton* firstButton = new QPushButton("First Button", this);
QPushButton* secondButton = new QPushButton("Second Button", this);
QPushButton* thirdButton = new QPushButton("Third Button", this);
// Create your (custom) widgets
QLabel* firstPageWidget = new QLabel("First Label", this);
QLabel* secondPageWidget = new QLabel("Second Label", this);
QLabel* thirdPageWidget = new QLabel("Third Label", this);
// Add them to the stackWidget
/*QStackedWidget* */ m_stackedWidget = new QStackedWidget(this);
m_stackedWidget->addWidget(firstPageWidget);
m_stackedWidget->addWidget(secondPageWidget);
m_stackedWidget->addWidget(thirdPageWidget);
// Insert buttons and stackWidget to CustomWidget
QVBoxLayout* layoutStack = new QVBoxLayout();
layoutStack->addWidget(m_stackedWidget);
QVBoxLayout* layoutButtons = new QVBoxLayout();
layoutButtons->addWidget(firstButton);
layoutButtons->addWidget(secondButton);
layoutButtons->addWidget(thirdButton);
QHBoxLayout* layout = new QHBoxLayout();
layout->addLayout(layoutButtons);
layout->addLayout(layoutStack);
setLayout(layout);
// Connect button clicks to slots
connect(firstButton, SIGNAL(clicked()), this, SLOT(onFirstButtonClicked()));
connect(secondButton, SIGNAL(clicked()), this, SLOT(onSecondButtonClicked()));
connect(thirdButton, SIGNAL(clicked()), this, SLOT(onThirdButtonClicked()));
Then you change the currently visible widget in the slots:
void CustomWidget::onFirstButtonClicked() {
m_stackedWidget->setCurrentIndex(0);
}
void CustomWidget::onSecondButtonClicked() {
m_stackedWidget->setCurrentIndex(1);
}
void CustomWidget::onThirdButtonClicked() {
m_stackedWidget->setCurrentIndex(2);
}
Note that if you want the button clicks just to simply change some text (as opposed to change the visible widget), you probably better use a QTextEdit instead of a QStackedWidget, and in the slots call setText("....");
If you have a lot of buttons, you'd better use QSignalMapper to limit the number of slots.
Also, I didn't get why you mentioned QDockWidget since they have a quite specific usage:
The QDockWidget class provides a widget that can be docked inside a QMainWindow or floated as a top-level window on the desktop.
QDockWidget provides the concept of dock widgets, also know as tool palettes or utility windows. Dock windows are secondary windows placed in the dock widget area around the central widget in a QMainWindow.
If you simply want a separate window, you're probably looking for a QDialog
How to do this with QtDesigner:
First you would prepare an appropriate user interface (contains 3 buttons and a single QStackedWidget on the right area to view each user control after clicking one of the added buttons).
Adding 3 pages for the user controls in the stack (+ one for the "empty" page if you really need that). If you want to design the Controls in separate UI Files / Only in Code (instead of all controls in your MainFrame), you would add plain QWidgets and promote them to the appropriate specific widget type
Inserting the content on each user control...
Implementing code for the 3 buttons on the frmMain.cpp/.h as the following (for this implementation we will be implementing the "Welcome" button carrying the object name as welcomeBtn, and the rest will have identical code but different user control names instead):
void FrmMain::on_welcomeBtn_clicked() {
ui->stack->setCurrentWidget(ui->welcomeWidget);
}
Select the "empty" page at as the current page in the designer, so the program will end up initially like this when running: (your screenshot)
When you click on the "Welcome" button for example, the result should be expected to be like this: (your second screenshot)
In my opinion, Miki's answer is the only correct approach to this use case (using a QStackedWidget).
For sake of completeness, I'll demonstrate how the same Clear and Add method as used in .NET is done in Qt:
// Assume controlPanel is a QWidget where you want to place the items
// Assume that controlPanel has set a layout (e.g. QHBoxLayout)
// Clear: Remove all Items from layout
QLayoutItem *child;
while ((child = controlPanel->layout()->takeAt(0)) != NULL) {
delete child;
}
// Now widgets are still there, but not layouted. Delete them explicitly
foreach (QWidget * w, controlPanel->findChildren<QWidget*>()) {
w->deleteLater();
}
// Now controlPanel is cleared
// Add new control
controlPanel->layout()->addWidget(new MyNewControlWidget);
First is, we can not force how other framework works to another one. Each framework has its flow and design.
What I am understand is you want to show another widget to the main window.
If you want to use the QDockWidget, its says on the documentation like this :
void QDockWidget::setWidget(QWidget * widget)
Sets the widget for the dock widget to widget.
If the dock widget is visible when widget is added, you must show() it explicitly.
Note that you must add the layout of the widget before you call this function; if not, the widget will not be visible.
Please share here you code of myWidget, so we can try to help you to figure out what is wrong.
On my side, I can achieve it by add the QVboxLayout on your ui->dockwidget and add QLabel with emtpy string and when you want to show myWidget just call ui->dockwidget->vboxlayout->replaceWidget(label, myWidget);
I want to write a coded UI test like "Some WPF control when some condition should not be visible". How do I assert "is not visible"?
To reproduce the issue:
create new WPF app
add nothing but one big named button into the main window
go to CUIT editor and recognize the button
without closing the CUIT editor close the WPF app
add Visibility="Hidden" to the button
restart the app
select the button in the CUIT editor and press "refresh" button
NOTE: the properties of the hidden button are exactly the same as properties of visible button!
There's no way to assert that the button is hidden!
Additionally:
I would be glad to hear about workarounds you're using. After all what I need is to write the test, not figure out CUITs
I am aware that I can compare screenshots
Interestingly if you try to do stuff with the hidden button the CUIT will throw. It implies that the CUIT knows when a button is hidden.
Interestingly if Visibility="Collapsed" instead of "Hidden" CUIT will recognize it by reporting Width = Height = -1. That doesn't help with collapsed buttons though :(
I've found the best way to work around the IsVisible limitation is to use the TryGetClickablePoint(out System.Drawing.Point) method of the UITestControl object. This method will return a Boolean value. So, for example, if you have a WpfButton:
WpfButton mine = new WpfButton(parent);
mine.SearchProperties["id"] = "id";
Point toString;
bool result = mine.TryGetClickablePoint(out toString);
Assert.IsTrue(result, "My Assertion here.");
That has worked more often than not. To handle collapsed or expanded, though, is there some property of the object that changes based on its state? For example, if the class is class="myobject expanded", you could easily assert based onmine.GetProperty("Class").ToString().Contains("expanded"); as a Boolean value.
Try to use GetProperty method:
WpfButton myButton = new WpfButton();
if(myButton.GetProperty("Enabled").Equals(true))
{
... CODE
}
I want to create simple wizard with 3 pages
Page 1 have just next button
Page 2 have next and previous
Page 3 have previous and finish
I have created the pages and add to them needed buttons and in the events I have call to the next pages, for instance in page one in the button click I added the following code
private void Button_Click(object sender, RoutedEventArgs e)
{
p2 = new Page2();
NavigationService.Navigate(p2);
}
In the main window cs I have changed the inheritance to NavigationWindow instead of Window and in the xaml also. Currently its working but I have 3 questions.
The pages which displayed is part of the main window, how can i avoid it, since when I run it the buttons place is not like I put in the designer? It was changed.
The button currently in the Grid, should I put them in different control (the button place should be like any wizard in the left buttom of the page) ?
How can I avoid the navigation arrows in the page right upper screen?
Thanks!
To answer your questsions in reverse,
3. How can I avoid the navigation arrows in the page upper right screen?
I have an opensource library http://winchrome.codeplex.com/ that re-styles navigation windows in several ways. For example these are all NavigationWindow s
In short you just style the NavigationWindow to only show the parts you want.
2.The button currently in the Grid, should I put them in different control (the button place should be like any wizard in the left buttom of the page) ?
If you look at the styles from WinChrome then you will see that it is just a case of rebuiliding the UI as you want and providing a ContentPresenter to hold your pages. e.g. the VS2012 style applies lots of styles on the window but avoids adding back and forward buttons., whereas the Win7 style rebuilds the back and forwards in a Win7 Style.
If you do this however you will need a means of passing your enabled or visible states to the buttons outside the pages. Take a look at http://www.codeproject.com/Articles/8197/Designer-centric-Wizard-control for how to do this in Winforms. In WPF you could either derive from your Pages to create WizardPage classes with CanBack, CanNext or IsFinish properties, or alteratively define attached properties to do the same (There are examples of how to do this in VS2012.cs where we define the glow color)
And finally
1. The pages which displayed is part of the main window, how can i avoid it, since when I run it the buttons place is not like I put in the designer? It was changed.
I'd need to see some code to comment on how you've done it, but if you look at any of the demo programs in WinChrome then you can see how I've done it without problems.
Good luck!
how to get a popin effect in silverlight on fly (in c# and not in XAML). by popin effect effect I mean:
Lets suppose I have two containers (a container could be a grid, pane etc) aligned vertically and theres a button on top on. On pressing the button an another container would emerge (which was invisible till now) from the top container and would slide down the already existing below container slowly.
I need the code syntax and not any already existing custom or standard component for this.
Thanks...
The scenario you described look like job for 'DataState behavior'. I usually create 2 'States' under 'Default states' such as: NormalState (the 'default ' state) and 'WorkingState' (that's include 'Busy' icon and my be fade-out screen a little bit) or even use FluidMove or Styoryline as in your example. Then create a simple public bool IsWorking {get;set;} property and attach 'DateState' behavior to it's boolean answer. So in case when IsWorking is 'true' show/run 'WorkingState' and in case of 'false' show 'NormalState'.
It's very easy to set automatically in GUI/Blend. It follows principles of MVVM pattern and testable.
The state change mechanism has 'TransitState' property - most of them build-in but very flexible. You can create a StoryLine as starting point of 'WorkingState' and slide the Components there (It's different state so you can set 'Visible' and other properties without changing it globally or managing state in code logic). You also can create independent Storyline and run it on some event rising from code but again - the preferred way it's to use DateState behavior.
I am working on windows application form. I have a CustomControl (say MasterControl) on which i put a split panel and now my MasterControl is split into three parts say:
Pannel1
Pannel2
Pannel3
Now i develop three custom controls and put one in each of pannels e.g
Pannel1 have CustomControl1
Pannel2 have CustomControl2
Pannel3 have CustomControl3
Now somewhere in CustomControl3 I need to access a public member of CustomControl1. For which i wrote the following code:
((MasterControl)this.Parent)._oCustomControl1.PublicMember = this.PublicMember;
The code above doen't work in my case. When this line of code is executed in debug mode then a message box appears and states that "There is no code available for current location"
It's a really bad design for your controls to depend on how are the arranged on the parent container.
e.g. inside your third control, you are quering the property of the first one by accessing it from the parent, and then it's child control by name.
Your code will break very easily, if it can be compiled at all - I think the problem you're having is the order of compilation: in order for your parent form to be compiled, it needs to have child user controls finished. On the other hand the user controls you created need to have finished form.
It would be far better to set whatever behaviour you're after from the container of those controls - for example, by reacting to events from the control, and setting appropriate stuff on appropriate other controls (there are other ways as well ofcourse - the point is in the direction and flow of information - who's setting and using what).
If you have a split panel in your master control, you should go two levels up to find your master control:
((MasterControl)this.Parent.Parent)._oCustomControl1.PublicMember = this.PublicMember;
I found the answer by myself. I am positing here because it might help some one else.
The exact code is:
((MasterControl)this.Parent.Parent.Parent)._oCustomControl1.PublicMember = this.PublicMember;
Basically my coustomcontrol3 lies inside a split container panel, so when i wrote:
this.Parent then it points to Panel In which it is residing and if i wrote
this.Parent.Parent then it points to the spliter container in which above panel reside and if i wrote
this.Parent.Parent.Parent then it points to control in which this split container resides
I got the idea from "Farzin Zaker" answer, so thanks to him for his contribution