how to Acces a Button/Textbox..... from mainwindow in class - c#

Im new at OOP and im wondering how i can say in my edit Class, get this textbox from the mainwindow and clear it. I tried this:
public partial class MainWindow : Window
{
Edit edit = new Edit();
public MainWindow()
{
InitializeComponent();
}
private void ClearBtn_Click(object sender, RoutedEventArgs e)
{
//TxtBox.Clear();
edit.Clear();
}
}
Edit class
public class Edit
{
MainWindow main = new MainWindow();
public void Clear()
{
main.TxtBox.Clear();
}
public Edit()
{
}
}

It's unclear to me why you would need to clear the MainWindow's text box from another class, as it's not practical in a real-world situation, but here you go:
public class Edit
{
public void Clear(MainWindow window)
{
window.TxtBox.Clear();
}
}
Another way to do it would be to pass the MainWindow into the Edit class's constructor, because I can see that you are instantiating Edit from the MainWindow class anyways.
public class Edit
{
private MainWindow _window;
public Edit(MainWindow window)
{
_window = window;
}
public void Clear()
{
_window.TxtBox.Clear();
}
}

if you wish to access controls of MainWindow from different classes you could use a similiar code:
MainWindow MWin = (MainWindow)Application.Current.MainWindow;
MWin.TxtBox.Clear();

Related

How to make the WPF app to, open only one new window or create only single instance of the XAML, when clicking button in MainWindow?

I have a WPF application and here is the application structure:
Views
MainWindow.xaml, ABC.xaml (all with .cs files)
ViewModels
MainWindowVM.cs, ABCVM.cs
I have a Button in MainWindow.xaml (bound to MainWindowVM.cs) that calls a function, SampleFunction() in MainWindowVM.cs when being clicked and the SampleFunction() then creates a new instance of ABC.xaml (bound to ABCVM.cs) and open a new window of ABC.xaml using Show() function.
How can I make sure that clicking the Button in MainWindow would not open another new window of ABC.xaml when the old window is still there, or not create another new instance of ABC.xaml?
MainWindow.xaml.cs
public partial class MainWindow : Window
{
/*...Some other codes...*/
private MainWindowVM _VM = new MainWindowVM();
public MainWindowVM MainWindowVM
{
get { return _VM; }
set { _VM= value; }
}
public MainWindow()
{
InitializeComponent();
this.DataContext = MainWindowVM;
}
private void SomeControl_MouseLeftButtonUp(object sender,MouseButtonEventArgs e)
{
MainWindowVM.SampleFunction();
}
}
MainWindowVM.cs
public class MainWindowVM
{
/*...Some other codes...*/
public void SampleFunction()
{
ABC abc= new ABC();
abc.Show();
}
}
ABC.xaml.cs
public partial class ABC: Window
{
/*...Some other codes...*/
private static ABCVM _abcVM= new ABCVM();
public ABCVM ABCVM { get { return _abcVM; } set { _abcVM = value; } }
public ABC()
{
InitializeComponent();
this.DataContext = ABCVM;
}
}
Use ShowDialog() instead of Show().
Then you have to close the ABC.xaml first, before you can make something on the MainWindow. So you can't open a second ABC.xaml Window.
You can write code to check whether a window type object exists or not.
for each(Window win in Application.Current.Windows)
{
string windowType = win.GetType().ToString();
if (!windowType.Equals(nameSpace + "." + ABC))
{
ABC abc= new ABC();
abc.Show();
}
}

Stackoverflow Exception because of 'this.Content'?

So this sounds strange but I always get a stackoverflow exception when I execute 'this.Content' 3 times.
So I have a main window which stores all userControls so I dont have to create them always:
public partial class MainWindow : Window
{
CreateSessionWindow csw;
RateSessionWindow rsw;
CloseSessionWindow closesw;
MainMenuWindow mmw;
public MainWindow()
{
InitializeComponent();
csw = new CreateSessionWindow();
rsw = new RateSessionWindow();
closesw = new CloseSessionWindow();
mmw = new MainMenuWindow();
AllSessionWindows.csw = csw;
AllSessionWindows.rsw = rsw;
AllSessionWindows.closesw = closesw;
AllSessionWindows.mmw = mmw;
}
private void bttnStartProgram_Click(object sender, RoutedEventArgs e)
{
this.Content = AllSessionWindows.mmw;
}
}
public static class AllSessionWindows
{
public static RateSessionWindow rsw;
public static CloseSessionWindow closesw;
public static CreateSessionWindow csw;
public static MainMenuWindow mmw;
}
In my MainMenuWindow class I have a button and when I click on the button it changes the content:
public partial class MainMenuWindow : UserControl
{
public MainMenuWindow()
{
InitializeComponent();
}
private void bttnCreateSession_Click(object sender, RoutedEventArgs e)
{
this.Content = AllSessionWindows.csw; //here
}
}
And here is where I get usually the stackoverflowexception:
public partial class CreateSessionWindow : UserControl
{
public CreateSessionWindow()
{
InitializeComponent();
}
private void bttnGoBack_Click(object sender, RoutedEventArgs e)
{
this.Content = AllSessionWindows.mmw; //here I always get the exception
}
}
So no matter in which order I call this.Content (for eg. first mmw and than csw or csw and than mmw) I always get a stackoverflow Exception when I call it 3 times which you can see above. What could be the problem be?
The problem in your code is this.Content=... in UserControls (in this case this.Content is UserControl content not Window content). If you want to change content in the main window you should add property with MainWindow to class AllSessionWindows:
public static class AllSessionWindows
{
public static MainWindow MainWindow;
public static RateSessionWindow rsw;
public static CloseSessionWindow closesw;
public static CreateSessionWindow csw;
public static MainMenuWindow mmw;
}
In the MainWidnow constructor you must assign this property:
public MainWindow()
{
InitializeComponent();
...
AllSessionWindows.MainWindow = this;
}
And in UserControl you should use following code:
private void bttnCreateSession_Click(object sender, RoutedEventArgs e)
{
AllSessionWindows.MainWindow.Content = AllSessionWindows.csw;
}
Presented solution to this kind of problem by you is not the best solution. For this kind of problem, you can use Caliburn.Micro framework.
In the following link you can find a good tutorial:
http://www.mindscapehq.com/blog/index.php/2012/1/12/caliburn-micro-part-1-getting-started/
Your problem is described in part 5 and 6 of this tutorial.

Assign values to a variable of a class and use that value to assign to another variable from another class

I'm having trouble assigning the value of a variable from one class to another class. I have tried to do it in several ways but none works, the variable still has no value inside my method.
First Class:
namespace Simulador
{
public partial class Cidade : Window
{
private int QNTTodinho;
private void todinhobotao_Click(object sender, RoutedEventArgs e)
{
TodinhoBotaoo();
}
public void TodinhoBotaoo()
{
QNTTodinho += 1;
MainWindow Valor = new MainWindow(QNTTodinho);
}
}
}
Second Class:
namespace Simulador
{
public partial class MainWindow : Window
{
private int QNTTodinho;
public MainWindow(int qNTTodinho)
{
QNTTodinho = Convert.ToInt32(qNTTodinho);
}
private void Salgadinho_Click(object sender, RoutedEventArgs e)
{
Dinheiro22.Content = QNTTodinho.ToString();
}
}
}
I am guessing that the startup form for your application is
MainWindow. Which means you are creating an instance of MainWindow and running it as the main application window.
If this is the case, then creating another instance of MainWindow like what you are doing and passing the integer to it in the constructor wouldn't affect the actual main window. It is just setting the value in a copy of the MainWindow and directly scrapping that copy afterwards.
One way to fix that, although not the best practice, is to change the member you want to modify to be a static member, like that:
public partial class MainWindow : Window
{
public static int QntTodinho { get; set; }
public MainWindow()
{
}
private void Salgadinho_Click(object sender, RoutedEventArgs e)
{
Dinheiro22.Content = this.QntTodinho.ToString();
}
}
public partial class Cidade : Window
{
private int qntTodinho = 0;
private void todinhobotao_Click(object sender, RoutedEventArgs e)
{
TodinhoBotaoo();
}
public void TodinhoBotaoo()
{
this.qntTodinho += 1;
MainWindow.QntTodinho = this.qntTodinho;
}
}
Notice as well that I've done the following changes:
Used pascalCasing for private member
Used CamelCasing for public member
Get rid of Convert.ToInt32 as it is not needed
Things to consider with this solution are mainly thread safety and the lack of ways to notify MainWindow when the value changes.

C# display image in WPF from a custom class other than MainWindow : Window

Hello I have a simple WPF window and I want to load and display a logo image on specific "Image" item. The following code works perfectly and I can display the logo.
namespace WPFexample
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var uri = new Uri("pack://application:,,,/Assets/Logo.png");
LogoImage.Source = new BitmapImage(uri);
}
}
}
Now I want to create another class which can access the GUI and display from there the logo:
namespace WPFexample
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
class MyClass
{
private void myCustomDisplay()
{
var uri = new Uri("pack://application:,,,/Assets/Logo.png");
// How can I call the LogoImage.Source from this place??
}
}
}
Initially I thought that I could do this but nothing happened:
class MyClass
{
private void myCustomDisplay()
{
MainWindow MainWindowClassRef = new MainWindow();
var uri = new Uri("pack://application:,,,/Assets/Logo.png");
MainWindowClassRef.LogoImage.Source = new BitmapImage(uri);
}
}
Any suggestion why I cannot display it?
This does not work either:
namespace WPFexample
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public void DisplayInGUI()
{
var uri = new Uri("pack://application:,,,/Assets/ITLLogo.png");
LogoImage.Source = new BitmapImage(uri);
}
}
class MyClass:MainWindow
{
public void myCustomDisplay()
{
DisplayInGUI()
}
}
}
To access a member (e.g. property or method) of the MainWindow instance, you can cast the MainWindow property of the current Application instance to your MainWindow class.
So e.g. call the MainWindow's DisplayInGUI() method by
((MainWindow)Application.Current.MainWindow).DisplayInGUI();
You probably want to pass the actual logo image as parameter to a method like
public partial class MainWindow : Window
{
...
public void SetLogoImage(ImageSource image)
{
LogoImage.Source = image;
}
}
and call it like this:
((MainWindow)Application.Current.MainWindow).SetLogoImage(
new BitmapImage(new Uri("pack://application:,,,/Assets/ITLLogo.png")));
EDIT: Call the method from another thread like this:
var mainWindow = (MainWindow)Application.Current.MainWindow;
mainWindow.Dispatcher.Invoke(() => mainWindow.DisplayInGUI());
MyClass needs to have a property or field called LogoImage. The "partial" keyword indicates that MainWindow has part of its class definition somewhere else - probably in a class called MainWindow.xaml. I would try looking at that file and moving the relevant portions of it to MyClass.
It might also help for MyClass to derive indirectly from UIElement. If you ask your IDE to create it as a UserControl in a new file, it will probably generate some placeholder xaml for you as well.

Multiple window WPF application: Sending values and sharing data

I'm new to WPF and have currently set up a 1 window WPF.
Now however I need a new window to share a Dictionary clientData;
When I click the entry in a ListBox in the main window I need to pass the entryId to the new window that can acces the clientData[entryId].
I've always made single window apps in the past so again I'm new to this.
How is this done?
Generally there are two easy possibilities to communicate between two windows.
Possibility 1:
You create public and static variables in both windows like this:
public static int Property1 { get; set; }
Possibility 2:
You create a parameterized method to show your subwindow and return your variables as public like this:
public int Property2 { get; set; }
public void ShowThis(int parameter)//Gets called by your MainWindow
{
this.Property2 = parameter;
this.Show();
}
EDIT
Based to your problem:
Your subwindow:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
public void ShowThis<T>(IEnumerable<T> data)
{
listBox.Items.Clear();
foreach(var item in data)
{
listBox.Items.Add(item);
}
this.Show();
}
}
And your MainWindow would look like this:
public partial class MainWindow : Window
{
Window1 window1;//your subwindow
public MainWindow()
{
InitializeComponent();
window1 = new Window1();
}
private void buttonShow_Click(object sender, RoutedEventArgs e)//button to show subwindow
{
int[] testData = new int[5] { 1, 3, 5, 7, 9 };
window1.ShowThis(testData);
}
}

Categories