I'm having two issues which I'm pretty sure are separate in WPF. First off boolean xs isn't getting passed into the Main Window which I've checked by testing where it is true and where it isn't. Also Cross 1 and Cross 2 do not draw if I add them to the Stack Panel in a button click event. Sorry about it being two pretty basic questions but I can't find anything that works. Also I tried to spare you guys as much reading as possible so if you need anything else to make it work for whatever reason don't hesitate to ask for it.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
StackPanel myStackPanel = new StackPanel();
Rectangle Rectangle = new Rectangle();
Rectangle.MouseLeftButtonDown += Rectangle8_MouseLeftButtonDown;
Rectangle Cross1 = new Rectangle();
Rectangle Cross2 = new Rectangle();
myStackPanel.Children.Add(Rectangle8);
bool xs = Menu.Xs;
bool os = Menu.Os;
bool RectangleClicked = false;
void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
RectangleClicked = true;
}
void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
RectangleClicked = true;
}
if (RectangleClicked == true)
{
myStackPanel.Children.Add(Cross2);
myStackPanel.Children.Add(Cross1);
}
if (xs == true)
{
MessageBox.Show("Xs is true");
}
}
}
Window Two Code
public partial class Menu : Window
{
public Menu()
{
InitializeComponent();
}
public static bool Xs { get; private set; }
public static bool Os { get; private set; }
public void Button_Click(object sender, RoutedEventArgs e)
{
Xs = true;
Os = false;
this.Close();
}
public void Button_Click_1(object sender, RoutedEventArgs e)
{
Xs = false;
Os = true;
MessageBox.Show("Xs is false");
this.Close();
}
}
}
The first issue with the Menu not returning the values:
You need an event to signal to main window that menu has closed and should retrieve the new values from menu.
In Menu, we add a delegate and event to signal that data has changed and the menu is closing:
public partial class Menu : Window
{
public delegate void DataChangeHandler(object sender, EventArgs e);
// an instance of the delegate
public DataChangeHandler DataChanged;
public Menu()
{
InitializeComponent();
}
public static bool Xs { get; private set; }
public static bool Os { get; private set; }
public void Button_Click(object sender, RoutedEventArgs e)
{
Xs = true;
Os = false;
DataChanged?.Invoke(this, new EventArgs());
this.Close();
}
public void Button_Click_1(object sender, RoutedEventArgs e)
{
Xs = false;
Os = true;
MessageBox.Show("Xs is false");
DataChanged?.Invoke(this, new EventArgs());//when menu closes announce change event if a handler is wired up to listen.
this.Close();
}
}
In MainWindow, we have two properties for x and o's being set from menu. These are outside the constructor.
public partial class MainWindow : Window
{
bool xs;
bool os;
public MainWindow()
{
//snip
Button Start = new Button();
Start.Height = 50;
Start.Width = 200;
Start.Margin = new Thickness(500, -100, 0, 0);
Start.Content = "Start";
myStackPanel.Children.Add(Start);
Start.Click += Start_Click;
xs = Menu.Xs;
os = Menu.Os;
}
private void Start_Click(object sender, RoutedEventArgs e)
{
Menu win2 = new Menu();
win2.DataChanged += MenuClosed; //handler
win2.Show();
}
public void MenuClosed(object sender, EventArgs e) //fires after closing menu
{
xs = Menu.Xs; //get new values from Menu for x and o
os = Menu.Os;
}
The second issue:Cross 1 and Cross 2 do not draw if I add them to the Stack Panel.
You need create new crosses and add them to the desired rectangle. First remove the handler to the rectangle clicked outside the constructor in Mainwindow.
void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
RectangleClicked = true;
HandleMove(); //draw a new cross either X or O to 'this' square
}
For each rectangle you add, add a handler to draw the right cross inside the clicked rectangle. The cross drawing handler would then check if x's or o's are set and draw the right cross and add the cross to the rectangle.
Related
I have this piece of code, where it runs a function (MouseTracker) after clicking on a label
this MouseTracker, should capture a mouse position x and y after pressing the OK in dialog result.
namespace AdvancedStashHelper
{
public partial class Settings : Form
{
public int xTemp;
public int yTemp;
public Settings()
{
InitializeComponent();
}
private void MouseTracker()
{
while (true)
{
var result = MessageBox.Show("Move your cursor to position and press ENTER");
if (result == DialogResult.OK)
{
xTemp = MousePosition.X;
yTemp = MousePosition.Y;
}
break;
}
}
private void orbTransLabel_Click(object sender, EventArgs e)
{
Thread thread = new(MouseTracker);
thread.Start();
orbTransXPos.Text = xTemp.ToString();
}
private void orbAltLabel_Click(object sender, EventArgs e)
{
Thread thread = new(MouseTracker);
thread.Start();
}
}
}
The problem here it's, first time when you click on the label, nothing happens, but after you click the second time, the value is updated with previous mouse position.
This should function like this:
click on label
run the dialog that says to press enter to capture mouse position
update the values on form after pressing ok
do this for all labels with different mouse position values
thanks all for your info the code was simply as it is
namespace AdvancedStashHelper
{
public partial class Settings : Form
{
public int xTemp;
public int yTemp;
public Settings()
{
InitializeComponent();
}
private void MouseTracker()
{
var result = MessageBox.Show("Move your cursor to position and press ENTER");
if (result == DialogResult.OK)
{
xTemp = MousePosition.X;
yTemp = MousePosition.Y;
}
}
private void orbTransLabel_Click(object sender, EventArgs e)
{
MouseTracker();
orbTransXPos.Text = xTemp.ToString();
orbTransYPos.Text = yTemp.ToString();
}
private void orbAltLabel_Click(object sender, EventArgs e)
{
MouseTracker();
orbAltXPos.Text = xTemp.ToString();
orbAltYPos.Text = yTemp.ToString();
}
}
}
I am new to C# and I want to utilize the forms with one another.
I have 2 forms. (1)MMCMLibrary_home and (2)MMCMLibrary_reserve.
In this project, I'm in the stage of changing the label background colors in Form 1 but can't seem to utilize Form 2 to process it.
These are my necessary codes so far:
FORM 1
namespace MMCM_Library
{
public partial class MMCMLibrary_home : Form
{
public static MMCMLibrary_home instance;
//DCR1 Labels
public Label lbl1_1;
public Label lbl1_2;
public Label lbl1_3;
public Label lbl1_4;
public MMCMLibrary_home()
{
InitializeComponent();
instance = this;
lbl1_1 = lblDCR1_9;
lbl1_2 = lblDCR2_11;
lbl1_3 = lblDCR1_1;
lbl1_4 = lblDCR1_3;
public void btnDCR1_Click(object sender, EventArgs e)
{
var reserveDCR1 = new MMCMLibrary_reserve();
reserveDCR1.Show();
}
public void btnDCR2_Click(object sender, EventArgs e)
{
var reserveDCR2 = new MMCMLibrary_reserve();
reserveDCR2.Show();
}
public void btnDCR3_Click(object sender, EventArgs e)
{
var reserveDCR3 = new MMCMLibrary_reserve();
reserveDCR3.Show();
}
public void btnDCR4_Click(object sender, EventArgs e)
{
var reserveDCR4 = new MMCMLibrary_reserve();
reserveDCR4.Show();
}
}
}
FORM 2
when I click any reserve now button in form 1 it will open form 2. However, if I pick a radio button, the background change will always be applied to Discussion Room 1 even I reserved for discussion room 2
namespace MMCM_Library
{
public partial class MMCMLibrary_reserve : Form
{
public static MMCMLibrary_reserve instance;
public MMCMLibrary_reserve()
{
InitializeComponent();
instance = this;
}
private void MMCMLibrary_reserve_Load(object sender, EventArgs e)
{
}
private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
{
}
private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
{
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
}
private void radioButton1_CheckedChanged_1(object sender, EventArgs e)
{
}
private void btnDCR1_Click(object sender, EventArgs e)
{
}
public void btnDCRoomsReserve_Click(object sender, EventArgs e)
{
if (rbtn9.Checked)
{
MMCMLibrary_home.instance.lbl1_1.BackColor = System.Drawing.Color.Red;
}
}
}
}
Can you help me to device an efficient way to solve this. Can you also suggest a database method suitable for my beginner project.
You've said that:
the background change will always be applied to Discussion Room 1
Well, yes. It seems you don't pass specific object into Form2. There's strightforward:
MMCMLibrary_home.instance.lbl1_1.BackColor = System.Drawing.Color.Red;
So you'll be always changing backcolor of lbl1_1 of your Form1. What needs to be done is to indicate which room has been selected. You can assign room after you click the button by passing the int parameter:
public void btnDCR1_Click(object sender, EventArgs e)
{
var reserveDCR1 = new MMCMLibrary_reserve(1);
reserveDCR1.Show();
}
or:
public void btnDCR2_Click(object sender, EventArgs e)
{
var reserveDCR2 = new MMCMLibrary_reserve(2);
reserveDCR2.Show();
}
Then, in Form2, at the very top, add something like:
int room; to be able to assign the room number in Form2:
public MMCMLibrary_reserve(int roomNumber)
{
InitializeComponent();
room = roomNumber;
instance = this;
}
And then you could just select room you clicked, by:
public void btnDCRoomsReserve_Click(object sender, EventArgs e)
{
if (rbtn9.Checked)
{
if(room == 1)
{
MMCMLibrary_home.instance.lbl1_1.BackColor = System.Drawing.Color.Red;
}
else if(room == 2)
{
MMCMLibrary_home.instance.lbl1_2.BackColor = System.Drawing.Color.Red;
}
else if(room == 3)
{
MMCMLibrary_home.instance.lbl1_3.BackColor = System.Drawing.Color.Red;
}
else if(room == 4)
{
MMCMLibrary_home.instance.lbl1_4.BackColor = System.Drawing.Color.Red;
}
}
else if(radioButton2.Checked)
{
//etc.
}
else if(radioButton3.Checked)
{
//etc.
}
else if(radioButton4.Checked)
{
//etc.
}
}
I think that was the problem. Try it and let us know.
Here is how it should work:
Window1: A button click opens a new window and hides the current window
(This page contains a few textboxes)
public void applyBtn_Click(object sender, EventArgs e)
{
...
DataDisplay dd = new DataDisplay();
dd.Visibility = Visibility.Visible;
...
}
New Window: A button click opens Window1 from the same state (all the checkboxes, and textbox should contain the values from the time it was closed)
private void settings_btn_Click(object sender, RoutedEventArgs e)
{
Filters filter = new Filters();
filter.Visibility = Visibility.Visible;
}
//As you can see I am calling a new instance instead of reopening the same hidden instance.
Instead of creating a new instance every time, I'd prefer to use the same instance every time. If any other not so complicated ways out there, feel free to shoot!
If I understand you correctly, I think it would be better to have a "MainWindow" managing the 2 changing windows You could have it handled on the 2 Windows events or by using delegates:
public partial class MainWindow : Window
{
static frmFilters filterWindowInstance = new frmFilters(OpenDataDisplay);
static frmDataDisplay dataWindowInstance = new frmDataDisplay(OpenFilters);
static void OpenFilters()
{
filterWindowInstance.Visibility = Visibility.Visible;
dataWindowInstance.Visibility = Visibility.Collapsed;
}
static void OpenDataDisplay()
{
filterWindowInstance.Visibility = Visibility.Collapsed;
dataWindowInstance.Visibility = Visibility.Visible;
}
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
OpenFilters();
Visibility = Visibility.Collapsed;
}
}
public partial class frmFilters : Window
{
Action CloseFilterOpenData;
public frmFilters(Action CloseFilterOpenDataToSet)
{
InitializeComponent();
CloseFilterOpenData = CloseFilterOpenDataToSet;
}
private void cmdHideThis_Click(object sender, RoutedEventArgs e)
{
CloseFilterOpenData();
}
}
public partial class frmDataDisplay : Window
{
Action CloseDataOpenFilter;
public frmDataDisplay(Action CloseDataOpenFilterToSet)
{
InitializeComponent();
CloseDataOpenFilter = CloseDataOpenFilterToSet;
}
private void cmdHideThis_Click(object sender, RoutedEventArgs e)
{
CloseDataOpenFilter();
}
}
My main form is a mdi container with a menu strip. When I choose Options-Maintenance I want another mdi to appear. This kind of works. Instead of another mdi container along with the design, a regular smaller form appears and not sure why.
public partial class mdiMain : Form
{
static string sTo = ConfigurationManager.ConnectionStrings["connectionTo"].ToString();
public myDataAccess3 data;
public mdiMain()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
data = new myDataAccess3(sTo);
frmLogOn frmLogOn = new frmLogOn(data);
if (frmLogOn.ShowDialog().Equals(DialogResult.Cancel))
{
frmLogOn.Close();
frmLogOn = null;
Application.Exit();
return;
}
frmLogOn.Close();
frmLogOn = null;
this.Focus();
}
catch (Exception e1)
{
MessageBox.Show("There was an error " + e1);
}
}
private void maintenanceToolStripMenuItem_Click(object sender, EventArgs e)
{
mdiMaintenance maintenance = new mdiMaintenance(this,data);
maintenance.Enabled = true;
maintenance.Show();
}
}
public partial class mdiMaintenance : Form
{
private myDataAccess3 data;
private mdiMain mdiMain;
public mdiMaintenance()
{
InitializeComponent();
}
public mdiMaintenance(mdiMain mdiMain, myDataAccess3 data)
{
// TODO: Complete member initialization
this.mdiMain = mdiMain;
this.data = data;
}
private void mdiMaintenance_Load(object sender, EventArgs e)
{
}
Thanks for the help
If the form is intended to be an MDI Child then you need to set the MdiParent property:
private void maintenanceToolStripMenuItem_Click(object sender, EventArgs e)
{
mdiMaintenance maintenance = new mdiMaintenance(this,data);
maintenance.Enabled = true;
maintenance.MdiParent = this;
maintenance.Show();
}
so this code here dynamically adds buttons to my wpf windows application. I cant think of the way in which I can call buttons which actually runat server because they are randomly added.
namespace DynamicButtons
{
public partial class Window1
{
public Window1()
{
this.InitializeComponent();
populateButtons();
}
public void populateButtons()
{
int xPos;
int yPos;
Random ranNum = new Random();
for (int i = 0; i < 4; i++)
{
Button foo = new Button();
Style buttonStyle = Window.Resources["CurvedButton"] as Style;
int sizeValue = ranNum.Next(100);
foo.Width = sizeValue;
foo.Height = sizeValue;
xPos = ranNum.Next(200);
yPos = ranNum.Next(300);
foo.HorizontalAlignment = HorizontalAlignment.Left;
foo.VerticalAlignment = VerticalAlignment.Top;
foo.Margin = new Thickness(xPos, yPos, 0, 0);
foo.Style = buttonStyle;
foo.Name = "button" + i;
foo.Click += new RoutedEventHandler(buttonClick);
LayoutRoot.Children.Add(foo);
}
}
private void buttonClick(object sender, EventArgs e)
{
Button clicked = (Button) sender;
// something like certainWindowsButton((i)<-this has to be based on above code) = clicked.Name();
MessageBox.Show("Button's name is: " + clicked.Name);
}
}
}
Every time the application runs the buttons are randomly assigned, what I want is a way in which I can interact with them from the code behind.
So
foo.Name = "button" + i;
means when or whichever button is clicked a number is assigned to it but how can I interact with that button in the code?
private void buttonClick(object sender, EventArgs e)
{
Button clicked = (Button) sender;
// something like certainWindowsButton((i)<-this has to be based on above code) = clicked.Name();
MessageBox.Show("Button's name is: " + clicked.Name);
}
}
I hope that makes sense.
To give you a sense of whats happening at design level:
Each of these grey squares are buttons each button is randomly assigned its designated name and number and each time the application runs these buttons will be reassigned a different number.
I need a way inwhich when a number is assigned to it I can then fire an event for that button clicked.
So randomly a button has been assigned number 1, take this number 1 and then assign it to
private void buttonClick(object sender, EventArgs e)
if
{
button1_Click = clicked.Name(strip away "button" and make sure the (variableNumber leftover matches button(1)_Click);
}
else
button2
etc etc
Which then fires my button event:
private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("yay each randomly assigned button now correlates with a real button event");
}
}
}
Is this more what you're looking for? This takes each buttonNClick handler and creates a button for it. This way you don't even need the "i".
partial class Window1 {
void button3Click(object sender, RoutedEventArgs e) {
//Whatever you want here
}
void button2Click(object sender, RoutedEventArgs e) {
//Whatever you want here
}
void button1Click(object sender, RoutedEventArgs e) {
//Whatever you want here
}
public Window1() {
this.InitializeComponent();
populateButtons();
}
public void populateButtons() {
int xPos;
int yPos;
Random ranNum = new Random();
foreach (var routedEventHandler in new RoutedEventHandler[] { button1Click, button2Click, button3Click }) {
Button foo = new Button();
int sizeValue = ranNum.Next(100);
foo.Width = sizeValue;
foo.Height = sizeValue;
xPos = ranNum.Next(200);
yPos = ranNum.Next(300);
foo.HorizontalAlignment = HorizontalAlignment.Left;
foo.VerticalAlignment = VerticalAlignment.Top;
foo.Margin = new Thickness(xPos, yPos, 0, 0);
foo.Click += routedEventHandler;
LayoutRoot.Children.Add(foo);
}
}
}
If you just want to choose an action based on the button name the below code may help. Obviously the doAction method calls will change as will your cases but hopefully the code gives you a good enough general idea.
private void buttonClick(object sender, EventArgs e)
{
Button clicked = (Button) sender;
ChooseAction(clicked.Name);
}
private void ChooseAction(string buttonName)
{
switch(buttonName)
{
case "button1": doAction1(); break;
case "button2": doAction2(); break;
case "button3": doAction3(); break;
case "button4": doAction4(); break;
case "button5": doAction5(); break;
default: doDefaultAction(); break;
}
}
private void doAction1()
{
Console.WriteLine("action 1");
}
private void doAction2()
{
Console.WriteLine("action 2");
}
private void doAction3()
{
Console.WriteLine("action 3");
}
private void doAction4()
{
Console.WriteLine("action 4");
}
private void doAction5()
{
Console.WriteLine("action 5");
}
private void doDefaultAction()
{
Console.WriteLine("button name not recognised, performing default action");
}
As lobsterism said, or you could have a list of commands, that you bind randomly to the buttons, instead of any of this. http://www.switchonthecode.com/tutorials/wpf-tutorial-command-bindings-and-custom-commands
here is a verbose sample:
public class CoolCommand : ICommand
{
#region ICommand Members
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
//do what you want :)
}
#endregion
}
var allCommands = new List<ICommand>();
allCommands.Add(new CoolCommand);
allCommands.Add(new OtherCoolCommand);
allCommands.Add(new ThirdCoolCommand);
private void assignButton(button)
{
var idx = new Random().nextInt(allCommands.Count-1);
var command = allComands[idx];
button.Command = command;
allCommands.remove(command);
}