Can't find WinWindow by property "Name" - c#

I've got the following problem:
I try to create a Coded UI Test in Visual Studio 2015 Enterprise Edition without using the Generator. I want to achieve the very simple thing of pressing a button and looking at the results.
My Forms are not directly WinForms, but it's the basis of them.
Here's what I'm trying to do:
public void CodedUITestTestMethod()
{
//1. Step: Log into the program
LogIntoProgram();
}
private void LogIntoProgram()
{
// Find the Login-Window
WinWindow loginWindow = GetWindowByTitle("Program - Login");
[...]
}
private WinWindow GetWindowByName(string title, UITestControl parent = null)
{
// If the Window has a parent, assign it to the window
WinWindow result = parent == null ? new WinWindow() : new WinWindow(parent);
result.SearchProperties.Add(WinWindow.PropertyNames.Name, title);
result.Find();
return result;
}
The [...] section is where I want to press the button. The problem occurs before that though, as I can't even find the window I'm looking for. It repeatedly throws the UITestControlNotFound exception, no matter if I use the Title or the Classname of the Form.
I got the feeling that I am missing a very major point, but I can't figure out which one.
Thanks for the help in advance,
SchwarzSkills :)

Start your application and pass it into the WinWindow
var app = ApplicationUnderTest.Launch("C:\\Windows\\System32\\myProgram.exe"
, "%windir%\\System32\\myProgram.exe");
WinWindow loginWindow = GetWindowByTitle("Program - Login", app);

Related

Change Window on Button Click

In my current solution I have 2 projects:
1) A ClassLibrary project containing models and view models and
2) a project called UI containing 2 windows, a LoginWindow and a MainWindow.
Currently, the UI project has a reference to the ClassLibrary project to get the view models. The problem arises when I want to change the window from the LoginWindow to the MainWindow. I have read some articles and searches the internet for a few days now, but nothing seems to give a satisfying result in terms of what I am actually looking for. Typically it concerns a single window maintaining/switching between multiple views. That's not what I want. I want the LoginWindow to change to the MainWindow and close the LoginWindow on a button click. How is this achievable?
Edit1: I guess I need to clarify that I am using MVVM and need to access appropiate view models. I can’t just make a new instance of a certain window whenever needed and show it while hiding the other.
Edit2:
public static class MainTest
{
public static int Test()
{
Thread app = new Thread((ThreadStart)delegate
{
LoginWindow login = new LoginWindow();
LoginViewModel loginVM = new LoginViewModel();
if (loginVM.IsLoggedIn == false)
{
return -1;
}
else
{
MainWindow mainWindow = new MainWindow();
mainWindow.Show();
}
}
app.SetApartmentState(ApartmentState.STA);
app.Start();
return 0;
}
}
[SOLVED] At return -1 I get an error saying: "Anonymous function converted to a void returning delegate cannot return a value"
At app.SetApartmentState(ApartmentState.STA);I get an error saying: Argument2: cannot convert from 'void' to 'int'. I assume this has something to do with the delegate, you've written at the very top of the code.
Edit3:
Try this,
In your app.config file define the StartupUri xaml as login.xaml :
Application x:Class="CapronCRM.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Login.xaml">
And in your login xaml, when the login attemt is successfull, call this code :
MainWindow mw = new MainWindow();
mw.Show();
this.Close();
I usually use a main class to do this.
Create a main class that has this method inside
public static int Main()
{
Thread app = new Thread((ThreadStart)delegate
{
MyLoginControl login = new MyLoginControl();
MyLoginVM lvm = new MyLoginVM();
login.DataConetxt = lvm;
login.ShowDialog();
if (lvm.IsLoginFailed)
{
return;
}
else
{
MainWindow myApp = new MainWindow();
MyAppVm avm = new MyAppVm();
myApp.DataContext = avm;
myApp.ShowDialog();
}
}
app.SetApartmentState(ApartmentState.STA);
app.Start();
return 0;
}
In your project Properties (in visual studio right click on your project --> Properties) in the application tab set your Main class as startup object
This will allow you to run the login and check also the result before starting the actual application, without shutting down when the login view return
EDIT: Added an example of how you can use your VM. The point is that you can do what you want in this method. It's only purpose is to prevent the application to shutdown when the login view return (normally a Dispose() would be launched internally causing the shutdown of the application on window return)
EDIT2: there was a little error in my code. Fixed

How to pass data from one form to another form textbox in windows application?

I'm trying to pass a variable from one form to another form textbox. The 'variable' is a result of a calculation based on the user inputs.
Below is the code for the parent form(RuleInsertForm) where I'm calling the subform(Helpformula) to get the user inputs.
public partial class RuleInsertForm : Form
{
public string helpformulainputs;
}
private void RuleInsertForm_Load(object sender,EventArgs e)
{
if (helpformulainputs=="")
{
textBox_Inputs.Text = "";
}
else
{
textBox_Inputs.Text = helpformulainputs;
}
}
Below is the code for the subform(Helpformula) where i'm passing the result variable(formulainputs) to the parent form(RuleInsertForm).
public partial class HelpFormula : Form
{
public string formulainputs = string.Empty;
private void button_generateformula_Click(objectsender, EventArgs e)
{
using (RuleInsertForm insertform = new RuleInsertForm())
{
insertform.helpformulainputs = formulainputs;
this.Close();
insertform.Show();
}
}
}
Problem:
The values are getting passed to the text box but in the UI its not getting dispalyed.
so far I tried to push data back to parent form and then tried to display the data in the textbox where I failed.(I dont know where it went wrong suggest me if I can resolve the below one)
Now I need an alternative method to this for eg: instead of pushing the data back to parent form i need to make the variable available for all the forms trying to use the subform(formulainputs)
How can I acheive this process ? any suggestions are much appreciated.
The problem seems to be that insertForm.Show() does not block the execution of your button handler. Show opens the insertform as non-modal.
So after insertform is opened, the execution is continued in button_generateformula_Click and when you exit the using block, the insertform is disposed and therefore closed.
To solve this you may call insertForm.ShowDialog() instead.
For different ways of communicating between Forms look here or simply type communicate between forms into the SO search box.

C# .NET Window won't show in front after double clicking on listview row

I have this one problem that I can't get over. I think it will be something really simple but I just was not able to find out.. I am trying to open new window here for editing contact when user double click on one row in listview. Window normally opens but the problem is it won't open in front of current main window but behind it so it is not visible and can easily confuse user. I have tried few methods like BringIntoView() or playing with focus but nothing helped.
Please help me with this. Thanks!
Code:
void ListViewItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
editContact();
}
private void editContact()
{
Window1 win = new Window1("edit");
DatabaseHandler handler = new DatabaseHandler();
win.Show();
List<Contact> listie = handler.GetContactList();
var selected = listview_contacts.SelectedItem as Contact;
win.textbox_id.Text = selected.cId.ToString();
win.textbox_name.Text = selected.Name.ToString();
win.textbox_address.Text = selected.Address.ToString();
win.textbox_email.Text = selected.Email.ToString();
win.textbox_name.Focus();
win.textbox_name.SelectionStart = win.textbox_name.Text.Length;
}
private void editContact()
{
using(Window1 win = new Window1("edit"))
{
DatabaseHandler handler = new DatabaseHandler();
List<Contact> listie = handler.GetContactList();
var selected = listview_contacts.SelectedItem as Contact;
win.textbox_id.Text = selected.cId.ToString();
win.textbox_name.Text = selected.Name.ToString();
win.textbox_address.Text = selected.Address.ToString();
win.textbox_email.Text = selected.Email.ToString();
win.textbox_name.Focus();
win.textbox_name.SelectionStart = win.textbox_name.Text.Length;
win.ShowDialog();
// do something with whatever win1 did.
// if its say OK Cancrl form
// if (win.ShowDialog() == DialogResult.OK) { // do something }
}
}
Will probably fix your issue. However without seeing the rest of your code, or knowing your intent, I can't tell you exactly how badly you've gone wrong.
For example at least all the code setting up win.textbox, should be in win...
Try
win.ShowDialog();
Which should open the new windows as a modal window.
You could try
win.Show(this);
This will enable the user to interact with the main form when your editing dialog opens.
Or you can try
win.ShowDialog();
This will block the main form when your editing dialog opens.

Implement browser in windows form using awesomium

I"m using Awesomium to try and implement webpages inside my windows form application.
I've used the the awesomium .NET samples but I just don't get the my tab with my homeurl.
When I run my project the status bar is floating inside my form and nothing else happens.
Anyone know where I can get a tut on how to do this or know what could be the problem?
public Laboratory() {
WebCoreConfig webConfig = new WebCoreConfig() {
SaveCacheAndCookies = true,
HomeURL = "http://www.google.com",
LogLevel = LogLevel.Verbose
};
// Using our executable as a child rendering process, is not
// available when debugging in VS.
if (!Process.GetCurrentProcess().ProcessName.EndsWith("vshost")) {
// We demonstrate using our own executable as child rendering process.
// Also see the entry point (Main function) in Program.cs.
webConfig.ChildProcessPath = WebCoreConfig.CHILD_PROCESS_SELF;
}
WebCore.Initialize(webConfig);
InitializeComponent();
}
#region methodes
#region OpenTab
internal WebDocument OpenTab(string url = null, string title = null) {
WebDocument doc = String.IsNullOrEmpty(url) ? new WebDocument() :
String.IsNullOrEmpty(title) ? new WebDocument(url) : new WebDocument(url, title);
doc.Show(dockPanel);
return doc;
}
#endregion
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
this.OpenTab();
}
I've redone the left panel completely and used the other example that was with the download, that works like a charm. It's very basic but that'll do for now.
I too had the same problem but i devised a work around for the problem . I implemented the main browser engine that needs to be rendered on every tab (WebDocument Page as per the example) as a user control . Then i used a DockPannel in the mainForm .
So i create an instance of the user control and then add this to an instance of the DockPannel and thus it creates a tab with the required structure .
In case you have still not found a solution or have problems , please leave down a comment and i'll put in some code to help you .

Detecting design mode from a Control's constructor

Following-on from this question, is it possible to detect whether one is in design or runtime mode from within an object's constructor?
I realise that this may not be possible, and that I'll have to change what I want, but for now I'm interested in this specific question.
You can use the LicenceUsageMode enumeration in the System.ComponentModel namespace:
bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
Are you looking for something like this:
public static bool IsInDesignMode()
{
if (Application.ExecutablePath.IndexOf("devenv.exe", StringComparison.OrdinalIgnoreCase) > -1)
{
return true;
}
return false;
}
You can also do it by checking process name:
if (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv")
return true;
Component ... as far as I know does not have the DesignMode property. This property is provided by Control. But the problem is when CustomControl is located in a Form in the designer, this CustomControl is running in runtime mode.
I have experienced that the DesignMode property works correct only in Form.
Controls(Forms, UserControls etc.) inherit Component class which has bool property DesignMode so:
if(DesignMode)
{
//If in design mode
}
IMPORTANT
There is a difference of using Windows Forms or WPF!!
They have different designers and and need different checks.
Additionally it's tricky when you mix Forms and WPF controls. (e.g. WPF controls inside of a Forms window)
If you have Windows Forms only, use this:
Boolean isInWpfDesignerMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
If you have WPF only, use this check:
Boolean isInFormsDesignerMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv");
If you have mixed usage of Forms and WPF, use a check like this:
Boolean isInWpfDesignerMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
Boolean isInFormsDesignerMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv");
if (isInWpfDesignerMode || isInFormsDesignerMode)
{
// is in any designer mode
}
else
{
// not in designer mode
}
To see the current mode you can show a MessageBox for debugging:
// show current mode
MessageBox.Show(String.Format("DESIGNER CHECK: WPF = {0} Forms = {1}", isInWpfDesignerMode, isInFormsDesignerMode));
Remark:
You need to add the namespaces System.ComponentModel and System.Diagnostics.
You should use Component.DesignMode property. As far as I know, this shouldn't be used from a constructor.
You can use this
if (DesignerProperties.GetIsInDesignMode(this))
{
...
}
Like many others, I have had this problem several times already when designing Windows Forms UserControls.
But today, I had a situation where none of the mentioned solutions worked for me.
The problem is, that LicenseManager.UsageMode only works reliably in the constructor, while DesignMode only works outside the constructor and not always. This is my experience, and this is what is said in a discussion on GitHub.
And another problem comes with inheritance, and embedding user controls in another user controls in another user controls. At the latest in the 2nd level of embedding a user controls, both ways fail!
This can be shown in the UserControls that I created for this test. Every UC has 3 labels:
its (project name) and type name
The values of
DesignMode (true: "DM=1"),
LicenseManager.UsageMode == LicenseUsageMode.Designtime, queried locally, (true: "local_LM-DT=1")
LicenseManager.UsageMode == LicenseUsageMode.Designtime, queried from a private field that was written in the constructor (true: "ctor_LM-DT=1")
all taken inside the constructor ("CTOR") and inside a method that was called from the constructor ("CFCtor")
The same values as in 2)
all taken inside the Load event ("Load()") and inside a method that was called from the Load event ("CFLoad")
The UserControls and the Form that I created are (all screenshots shown them in the WinForms Designer):
UserControl1:
contains 3 labels
The Designer does not execute the construtor or events, therefore the labels are not filled.
UserControl1a:
inherits from UserControl1
contains 2 more labels
The Designer executes the construtor and events of the parent UserControl.
UserControl2: contains
contains 3 labels
contains 1 UserControl1
contains 1 UserControl1a
The Designer executes the construtors and events of the embedded UserControls.
Only 1 level of embedding.
UserControl3:
contains 3 labels
contains 1 UserControl2
The Designer executes the construtors and events of the embedded UserControls.
2 level of embedding: The values inside the UserControl at 2nd embedding level are wrong.
Form1:
contains 3 labels
contains 1 UserControl1
contains 1 UserControl1a
contains 1 UserControl2
contains 1 UserControl3.
The Designer executes the construtors and events of the embedded UserControls.
3 level of embedding: The values inside the UserControl at 2nd and 3rd embedding level are wrong.
As you can see from the screenshots, "ctor_LM-DT" is always 1.
This means, that storing the value from the LicenseManager in a member field is necessary to get a valid status of the Designer usage:
private LicenseUsageMode m_ctorLMUsageMode = LicenseManager.UsageMode;
For the sake of completeness, here's some of my code that can be used to reproduce the test:
public static string CreateText(bool i_isInDesignMode, LicenseUsageMode i_localLicenseUsageMode, LicenseUsageMode i_ctorLicenseUsageMode)
{
return $"DM={(i_isInDesignMode ? 1 : 0)} local_LM-DT={(i_localLicenseUsageMode == LicenseUsageMode.Designtime ? 1 : 0)} ctor_LM-DT={(i_ctorLicenseUsageMode == LicenseUsageMode.Designtime ? 1 : 0)}";
}
The other UserControls are identical or similar:
public partial class UserControl1 : UserControl
{
private LicenseUsageMode m_ctorLMUsageMode = LicenseManager.UsageMode;
public UserControl1()
{
InitializeComponent();
label2.Text = $"CTOR: {CInitTester.CreateText (DesignMode, LicenseManager.UsageMode, m_ctorLMUsageMode)}";
CalledFromCtor();
}
private void UserControl1_Load(object sender, EventArgs e)
{
label3.Text = $"Load(): {CInitTester.CreateText(DesignMode, LicenseManager.UsageMode, m_ctorLMUsageMode)}";
CalledFromLoad();
}
private void CalledFromCtor()
{
label2.Text += $"\r\nCFCtor: {CInitTester.CreateText (DesignMode, LicenseManager.UsageMode, m_ctorLMUsageMode)}";
}
private void CalledFromLoad()
{
label3.Text += $"\r\nCFLoad: {CInitTester.CreateText (DesignMode, LicenseManager.UsageMode, m_ctorLMUsageMode)}";
}
}
Another interesting method is described on that blog: http://www.undermyhat.org/blog/2009/07/in-depth-a-definitive-guide-to-net-user-controls-usage-mode-designmode-or-usermode/
Basically, it tests for the executing assembly being statically referenced from the entry assembly. It circumvents the need to track assembly names ('devenv.exe', 'monodevelop.exe'..).
However, it does not work in all other scenarios, where the assembly is dynamically loaded (VSTO being one example).
With cooperation of the designer... It can be used in Controls, Components, in all places
private bool getDesignMode()
{
IDesignerHost host;
if (Site != null)
{
host = Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
if (host != null)
{
if (host.RootComponent.Site.DesignMode) MessageBox.Show("Design Mode");
else MessageBox.Show("Runtime Mode");
return host.RootComponent.Site.DesignMode;
}
}
MessageBox.Show("Runtime Mode");
return false;
}
MessageBox.Show( lines should be removed. It only makes me sure it works correctly.
This is the method I used in my project:
//use a Property or Field for keeping the info to avoid runtime computation
public static bool NotInDesignMode { get; } = IsNotInDesignMode();
private static bool IsNotInDesignMode()
{
/*
File.WriteAllLines(#"D:\1.log", new[]
{
LicenseManager.UsageMode.ToString(), //not always reliable, e.g. WPF app in Blend this will return RunTime
Process.GetCurrentProcess().ProcessName, //filename without extension
Process.GetCurrentProcess().MainModule.FileName, //full path
Process.GetCurrentProcess().MainModule.ModuleName, //filename
Assembly.GetEntryAssembly()?.Location, //null for WinForms app in VS IDE
Assembly.GetEntryAssembly()?.ToString(), //null for WinForms app in VS IDE
Assembly.GetExecutingAssembly().Location, //always return your project's output assembly info
Assembly.GetExecutingAssembly().ToString(), //always return your project's output assembly info
});
//*/
//LicenseManager.UsageMode will return RunTime if LicenseManager.context is not present.
//So you can not return true by judging it's value is RunTime.
if (LicenseUsageMode.Designtime == LicenseManager.UsageMode) return false;
var procName = Process.GetCurrentProcess().ProcessName.ToLower();
return "devenv" != procName //WinForms app in VS IDE
&& "xdesproc" != procName //WPF app in VS IDE/Blend
&& "blend" != procName //WinForms app in Blend
//other IDE's process name if you detected by log from above
;
}
Attention!!!: The code returned bool is indicating NOT in design mode!
I wasn't able to get any of these solutions to work for me in Visual Studio 2019 when creating a WinForms app on .NET Core 3.1.
Both Appllication.ProcessName and Process.ProcessName are returning "DesignToolsServer" for me and LicenseManager.UsageMode returns LicenseUsageMode.Runtime when the Control is in another control or just on a form itself.
I did get it to work using Application.ProcessName == "DesignToolsServer".
Yes, you can check for whether you're in "design mode" from within an object's constructor. But using the WinForms DesignMode property doesn't always work as expected. An alternative:
This is my technique to check DesignMode in C# using Visual Studio and it does work in constructors.
// add this class...
public static class Globals
{
static Globals() => DesignMode = true;
public static bool DesignMode { get; set; }
}
// and modify your existing class...
public static class Program
{
public static void Main()
{
Globals.DesignMode = false;
// ...
// ... and then the rest of your program
//
// in any of your code you can check Globals.DesignMode for
// the information you want.
}
}
This solution is lightweight and simple. The downside is that you have to remember to clear the flag in your Main code.
When checking for "design mode," we're essentially checking for whether our code is being executed because our whole program is being run or because parts of our code are being executed by the VS designer. With this solution, the flag only gets set to false when the whole program is being run.
The LicenseManager solution does not work inside OnPaint, neither does this.DesignMode. I resorted to the same solution as #Jarek.
Here's the cached version:
private static bool? isDesignMode;
private static bool IsDesignMode()
{
if (isDesignMode == null)
isDesignMode = (Process.GetCurrentProcess().ProcessName.ToLower().Contains("devenv"));
return isDesignMode.Value;
}
Be aware this will fail if you're using any third party IDE or if Microsoft (or your end-user) decide to change the name of the VS executable to something other than 'devenv'. The failure rate will be very low, just make sure you deal with any resulting errors that might occur in the code that fails as a result of this and you'll be fine.
If you want to run some lines when it is running but not in the Visual Studio designer, you should implement the DesignMode property as follows:
// this code is in the Load of my UserControl
if (this.DesignMode == false)
{
// This will only run in run time, not in the designer.
this.getUserTypes();
this.getWarehouses();
this.getCompanies();
}
private void CtrlSearcher_Load(object sender, EventArgs e)
{
if(!this.DesignMode) InitCombos();
}
Timers that are enabled by default can cause crash when using custom/user controls. Disable them by default, and enable only after design mode check
public chartAdapter()
{
try
{
//Initialize components come here
InitializeComponent();
//Design mode check
bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
if (designMode)
return;
//Enable timers ONLY after designmode check, or else crash
timerAutoConnect.Enabled = timerDraw.Enabled = true;

Categories