I've looked through the list of similar questions for this topic and couldn't find any examples which deal with my particular problem.
I'd like to start with the disclaimer that I'm not far off an absolute beginner.
Opening up a window in WPF is quite easy, I've done it before in a previous project and it worked fine.
However, I am struggling to do it again in this new project (login form). I have two classes, MainWindow and CreateAccount.
MainWindow has the event trigger for opening up the CreateAccount window.
private void Button_Click(object sender, RoutedEventArgs e)
{
var account = new CreateAccount();
account.Show();
this.Close();
}
Researching how to open up a new window in WPF gave me snippets very much like this one.
What I want to happen is for, upon triggering the button event, the window I've designed with an account creation form to appear. What instead happens is a blank window pops up with what I can only assume are default dimensions and no border text.
I don't understand how this can be as I specified exactly what I wanted. I don't get any errors either.
The CreateAccount class is mostly just some if statements (I don't want to hunker down with it until I sort out the current issue) and I can't find anything that would cause issue.
Both classes inherit from Window. I took a guess at what might be wrong, thinking 'maybe its an inheritance problem' and so tried to make CreateAccount inherit from MainWindow, but that threw an error which I now understand. Right now I'm lost as to what the problem is and since I don't know that, I can't find out the solution.
Is there anything wrong with the code? Someone suggested that it might be a DataContext issue, but even after looking that up I'm struggling to understand it.
Thank you.
EDIT: Because a lot of people were asking for more code with CreateAccount.xaml.cs(I thought we were only allowed to post snippets):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Login
{
/// <summary>
/// Interaction logic for CreateAccount.xaml
/// </summary>
public partial class CreateAccount : Window
{
public bool canProceedPass = false;
public bool canProceedUser = false;
public void MakeAccount()
{
InitializeComponent();
}
public void CheckTextInput()
{
if (NewUsername.Text != null && NewPassword.Text != null) {
canProceedUser = true;
}
else
{
canProceedUser = false;
MessageBox.Show("You haven't filled out all the required fields.");
}
}
public void CheckPassInput()
{
if (NewPassword.Text == ConfirmNewPassword.Text)
{
canProceedPass = true;
}else
{
return;
}
}
private void CreateAccountButton_Click(object sender, RoutedEventArgs e)
{
if (canProceedUser == true && canProceedPass == true)
{
//Add username and password to my SqlDb.
}
}
}
}
A constructor should have the same name as your Class with no return type, in your example the constructor should be:
public CreateAccount()
{
InitializeComponent();
}
Related
I have a C#/WPF app. There is a task running lengthy operations and it needs a way to show a dialog requesting users decision at some point. The task can't exit and be restarted. It needs to remain paused and wait for the dialog result. There are plenty ways to do it. How do I do it properly in MVVM? How do I request users interaction from business logic?
It highly depends on what you want to achieve and how your code is set up.
https://learn.microsoft.com/en-us/dotnet/framework/wpf/app-development/dialog-boxes-overview That is a great article about the built in dialogue boxes that comes with WPF, you can also create your own.
I have a separate dll for services. In there there is a MessageBoxService.
That service references a Window. I'll leave the implementation up to you.
My Service implements an interface to be injectable, it isn't but just in case it can be.
Here is the snippet of what it provides:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
namespace Services.MessageBox
{
public class MessageBoxService : IMessageBoxService
{
Dispatcher dispatcher;
private Window mainWindow;
public MessageBoxService()
{
dispatcher = Application.Current.Dispatcher;
mainWindow = Application.Current.MainWindow;
}
private void UIThread(Action execute)
{
dispatcher.Invoke(execute);
}
public void Show(string caption, string message)
{
UIThread(() =>
{
System.Windows.MessageBox.Show(mainWindow, message, caption, System.Windows.MessageBoxButton.OK);
});
}
public bool? ShowDialog(string caption, string message)
{
bool? result = null;
UIThread(() =>
{
result = new Windows.Modal(message, caption).ShowDialog(mainWindow);
});
return result;
}
}
}
Then you would use it like this in your ViewModel:
var answer = messageBoxService.ShowDialog("Title Here", "Message to display");
So this is the very first time I try to create a custom renderer. I followed this thread here: https://forums.xamarin.com/discussion/32264/how-can-i-change-switch-text-color-android. I took a look at the first guy who placed an example code. I tried to use it with my own renderer but It gives the following error:
Type or namespace 'controls' doesn't exist in 'saleskicker'
here is my code:
using System;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms;
using SalesKicker;
[assembly:ExportRenderer(typeof(SalesKicker.Controls.CustomSwitch), typeof(CustomSwitchRenderer))]
namespace SalesKicker
{
public class CustomSwitchRenderer : SwitchRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.TextOn = "AAN";
Control.TextOff = "UIT";
Control.SetTextColor(Color.White);
}
if (Control.Checked == true)
{
Control.SetBackgroundColor(Color.Green);
}
}
}
}
However, the error didn't show up when I had the class inside a folder called 'CustomRenderers'. But I think this shouldn't be such a big deal. What am I doing wrong here? Can someone please help me?
If you just want to change the Color, you don't need a CustomControl. And then you can replace the default renderer with your own.
[assembly:ExportRenderer(typeof(Switch), typeof(CustomSwitchRenderer))]
I got bug in my app and can not solve it.
Bug is - I can not use camera more than three times.
Code, that demonstrates it is here:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using PhoneApp1.Resources;
using System.Windows.Media;
using Microsoft.Devices;
namespace PhoneApp1
{
public partial class MainPage : PhoneApplicationPage
{
PhotoCamera aCamera = new PhotoCamera(CameraType.Primary);
// Constructor
public MainPage()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var cam = new camera_VM();
}
}
class camera_VM
{
public camera_VM()
{
VideoBrush __cameraView = new VideoBrush();
PhotoCamera aCamera = new PhotoCamera(CameraType.Primary);
__cameraView.SetSource(aCamera);
}
}
}
On third launch - it throws error:
{System.NotSupportedException: Specified method is not supported.
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.VideoBrush_SetExternalVideoPortSource(VideoBrush vb, String sPortName)
at Microsoft.Devices.Camera
Have no idea - what does it mean.
My guess that having Videobrush in code - bad idea, but have I another option? I got Grid in DataTemplate, that binds to VideoBrush object.
If I must properly dispose camera unit - can anyone tell me, how to do it right?
P.S. Code is just example, that fires an error.
I have an issue related to running CodedUITests from a Windows Form. (it works in the CodedUITestProject with Test-Explorer).
This is my CodedUITest's structure :
[CodedUITest]
public class DBTest
{
#region Static Fields
public static CSVReader csvReader;
#endregion
#region Fields
public string logFileName;
public string timer = String.Empty;
public TestRead testRead;
public UploadResults uploadResults;
private DateTime testStart;
#endregion
[ClassInitialize]
public static void MyTestInitialize(TestContext test)
{
csvReader = new CSVReader();
csvReader.LoadTestValues("steam.csv");
}
[TestInitialize]
public void testInit()
{
testStart = DateTime.Now;
}
[TestMethod(), TestCategory("Reflection"), TestCategory("DataDriven"), DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", #"|DataDirectory|\CSV's\steam.csv", "steam#csv", DataAccessMethod.Sequential), DeploymentItem(#"..\..\CSV's\steam.csv")]
public void steamAccess()
{
testRead = new TestRead();
SteamMap a = new SteamMap();
testRead.Read(a, TestContext);
}
[TestCleanup]
public void TestCleanup()
{
uploadResults = new UploadResults();
//timer for each test ( in seconds )
double diffSecs = (DateTime.Now - testStart).TotalSeconds;
uploadResults.TestUpload(testRead.TestResults, csvReader.DataTable, diffSecs,TestContext);
}
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
private TestContext testContextInstance;
}
This runs perfectly from VS's Test Explorer, testContextInitialize variable gets initialized.
In the same Solution I've added a second project, a simple Windows Form application, added a reference to my DLL ( from References) which runs the following code :
Playback.Initialize();
DBTest a = new DBTest();
a.steamAccess();
Playback.Cleanup();
NullReferenceException occurs, my testContex is null when I run my test from outside it's assembly.
I need some help in this matter, Thanks
Edit 1:
Test Class :
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Input;
using System.Windows.Forms;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UITesting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UITest.Extension;
using Keyboard = Microsoft.VisualStudio.TestTools.UITesting.Keyboard;
using System.Linq;
using System.Reflection;
using SimarpiDB.GLobal;
using SimarpiDB.UITestMaps.SteamMapClasses;
using SimarpiDB.Global;
using System.Data;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("TestLauncher")]
namespace SimarpiDB
{
[CodedUITest]
public class.....
Edit 2:
Temporary workaround until I find the cause of this error :
From my Windows Form I launch a MSTest with few required parameters and most of the what-methods-to-run logic will come from my database. I already did this few months ago but I scraped it because it's an additional performance overhead to use a tool such as MsTest within a launcher such as mine.
For anyone interested, there's a file located within VS's installation directory, it's called VsDevCmd.bat, I load this .bat within a hidden-in-background cmd with few additional commands ( mstest, testcontainer, test). This works but as I said I have no other plausible ideas.
There may also be a lack of referenced libraries within my Form ? Maybe something, a .dll that initialized the testenvironment and the testContext variable.
I wrote this because there may be others seeking the same result.
To clarify on my comment: internal is default in C#, so declaring something as abstract is like declaring it as "internal abstract".
For InternalsVisibleTo, you must make the library project visible to the test project, not the other way around:
[assembly:InternalsVisibleTo("MyTestProject")]
I’m pretty new to programming, so bear with me if my question isn’t specific enough. Right now I’m trying to make a simple Client Logon to my server. So the server App knows which users are connected. When a client connects I want an event to fire on the server that update the userlist. But it doesn’t and I can’t figure out why. Hope you can help.
In the codes I have removed how the users should be displayed in the serverApp. Right now I just need the event to work.
In my Service Library:
INetworkService contract:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace NetworkLib
{
[ServiceContract]
public interface INetworkService
{
[OperationContract]
void Logon(UserInfo userInfo);
[OperationContract]
void Logout();
}
}
NetworkService Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace NetworkLib
{
public class NetworkService : INetworkService
{
public event EventHandler UserListChanged;
public void Logon(UserInfo userInfo)
{
OnUserListChanged();
}
public void Logout()
{
OnUserListChanged();
}
private void OnUserListChanged()
{
var handler = UserListChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
}
UserInfo Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace NetworkLib
{
[DataContract]
public class UserInfo
{
[DataMember]
public string Name;
}
}
In my ServerApp (WPF):
using System.ServiceModel;
using NetworkLib;
namespace ServerApp
{
public partial class MainWindow : Window
{
NetworkService networkService;
public MainWindow()
{
InitializeComponent();
ServiceHost host = new ServiceHost(typeof(NetworkService));
host.Open();
networkService = new NetworkService();
networkService.UserListChanged += networkService_UserListChanged;
}
private void networkService_UserListChanged(object sender, EventArgs e)
{
MessageBox.Show("It Works!");
}
}
}
In my ClientApp (WPF): (Have made a Service Reference to the Server)
namespace ClientApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
ServiceReference.NetworkServiceClient proxy = new ServiceReference.NetworkServiceClient();
ServiceReference.UserInfo userInfo = new ServiceReference.UserInfo();
userInfo.Name = "Test";
proxy.Logon(userInfo);
}
}
}
You subscribe to event of other NetworkService instance than ServiceHost instantiates. In your case every time you make request to server, new NetworkService instance is created. Place the following attribute above NetworkService class:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
Then subscribe to event:
var serviceInstance = (NetworkService)host.SingletonInstance;
serviceInstance.UserListChanged += networkService_UserListChanged;
When creating your ServiceHost, you should provide NetworkService instance instead of typeof(NetworkService)
ServiceHost host = new ServiceHost(networkService);
You need to initialize it first, of course.
I didnt look in great detail but overall your code looks ok. It is sometimes useful in this situation to run 2 instances of VisualStudio - one for server in debug and one for client in debug. If you put a break point in client button1_Click code in VS thats debugging client, and a break point in NetworkServices.Logout in VS thats debugging server you will be able to step from client to server code and see easily whats going wrong where.
Why do you need an event model here? Why not just handle your "event" directly in NetworkService.Logout(). Does pushing this off to an event and then having to wire that event (which as ilya.dofofeev correctly points out is not on the same object) provide any real benefit?