Programmatically closing a WP7 Coding4Fun toolkit MessagePrompt Control - c#

I am using the MessagePrompt control from the Coding4Fun toolkit to show a "Rate and Review" dialog in my app.
I have replaced the default buttons with custom buttons as well as clearing the existing buttons (to get rid of the ticks and crosses) but cannot figure out which method to call to close the prompt.
This is the code I am using, Id like to close the prompt in the click method of the cancel button
var messagePrompt = new MessagePrompt
{
Title = "Rate and Review",
IsAppBarVisible = false,
Body = new TextBlock
{
Text = "PLS REVIEW MY APP K THNX",
TextWrapping = TextWrapping.Wrap
}
};
var rateButton = new Button() { Content = "Rate and Review" };
rateButton.Click += (sender, e) =>
{
var m = new MarketplaceDetailTask
{
ContentIdentifier = PhoneState.AppID,
ContentType = MarketplaceContentType.Applications
};
m.Show();
};
var cancelButton = new Button() { Content = "Dismiss" };
cancelButton.Click += (sender, e) =>
{
//todo close messagePrompt here
};
messagePrompt.ActionPopUpButtons.Clear();
messagePrompt.ActionPopUpButtons.Add(rateButton);
messagePrompt.ActionPopUpButtons.Add(cancelButton);
messagePrompt.Show();

The newest check in of the toolkit exposes the Hide() method to solve this.
cancelButton.Click += (sender, e) =>
{
messagePrompt.Hide();
};

Related

Why does the stackpanel ignore Orientation property?

I'd like to use a stackpanel with two textblock that have two uris, inside a ContentDialog. The problem is that despite I set the property to Vertical, it has no effect and that's the visual result
private async void AboutButton_Click(object sender, RoutedEventArgs e)
{
TextBlock gHRepoTB = new TextBlock();
Hyperlink hyperlink1 = new Hyperlink();
Run run1 = new Run();
run1.Text = "View GitHub repository";
hyperlink1.NavigateUri = new Uri("https://www.google.com/");
hyperlink1.Inlines.Add(run1);
gHRepoTB.Inlines.Add(hyperlink1);
TextBlock privacyPolicyTB = new TextBlock();
Hyperlink hyperlink2 = new Hyperlink();
Run run2 = new Run();
run2.Text = "Privacy Policy";
hyperlink2.NavigateUri = new Uri("https://www.bing.com/");
hyperlink2.Inlines.Add(run2);
gHRepoTB.Inlines.Add(hyperlink2);
StackPanel aboutPanel = new StackPanel();
aboutPanel.Orientation = Orientation.Vertical;
aboutPanel.Children.Add(gHRepoTB);
aboutPanel.Children.Add(privacyPolicyTB);
ContentDialog aboutDialog = new ContentDialog();
aboutDialog.Title = "About";
aboutDialog.Content = aboutPanel;
aboutDialog.PrimaryButtonText = "Report a bug";
aboutDialog.PrimaryButtonClick += ReportBug_Click;
aboutDialog.PrimaryButtonStyle = App.Current.Resources["AccentButtonStyle"] as Style;
aboutDialog.CloseButtonText = "Close";
await aboutDialog.ShowAsync();
}
#mm8 showed how to fix your problem, however this is the result of unnecessary and unclear code.
Here are the things I changed:
I've changed a button with hyperlink layout to a hyperlinkbutton.
I've set the contents to just a string since in this case no more is needed.
Instead of manually setting a style to the primarybutton, I've specified the DefaultButton
By creating the dialog this way, you are less prone to making mistakes, others and yourself later on will be able to tell faster what's going on, and less temporary variables are introduced.
The code (You should be able to copy this code directly over your current eventhandler):
private async void AboutButton_Click(object sender, RoutedEventArgs e)
{
StackPanel aboutPanel = new StackPanel();
aboutPanel.Children.Add(
new HyperlinkButton
{
Content = "View GitHub repository",
NavigateUri = new Uri("https://www.google.com/")
});
aboutPanel.Children.Add(
new HyperlinkButton
{
Content = "Privacy Policy",
NavigateUri = new Uri("https://www.bing.com/")
});
var dlg = new ContentDialog
{
Title = "About",
Content = aboutPanel,
PrimaryButtonText = "Report a bug",
DefaultButton = ContentDialogButton.Primary,
CloseButtonText = "Close"
};
dlg.PrimaryButtonClick += ReportBug_Click;
await dlg.ShowAsync();
}
See the result below:
You add the second Hyperlink to the wrong TextBlock. It should be privacyPolicyTB.Inlines.Add(hyperlink2);:
TextBlock privacyPolicyTB = new TextBlock();
Hyperlink hyperlink2 = new Hyperlink();
Run run2 = new Run();
run2.Text = "Privacy Policy";
hyperlink2.NavigateUri = new Uri("https://www.bing.com/");
hyperlink2.Inlines.Add(run2);
privacyPolicyTB.Inlines.Add(hyperlink2); //<-- here

Winform: Clean way to toggle visibility of a control on TextChanged in TextBox

I have a winform with many TextBox and a single message, I want the message to disappear when any of the TextBox are changed. Is there a clean way to achieve this without adding TextChanged EventHander to all TextBox ?
My messy way of doing it is as follows:
public static DialogResult ShowDialog()
{
var inputBox = new Form { ClientSize = new Size(520, 225), FormBorderStyle = FormBorderStyle.FixedDialog };
var input1 = new TextBox { Location = new Point(25, 25)};
var input2 = new TextBox { Location = new Point(25, 60) };
// Many more text boxes...
var label = new Label { Text = "Text", Location = new Point(25, 90), Visible = true };
input1.TextChanged += new EventHandler((sender, e) => label.Visible = false);
input2.TextChanged += new EventHandler((sender, e) => label.Visible = false);
// Add handler for all TextBoxes...
inputBox.Controls.Add(input1);
inputBox.Controls.Add(input2);
inputBox.Controls.Add(label);
return inputBox.ShowDialog();
}
You can try to write a function to create TextBox.
let TextBox initial setting and event binding code in the function.
private static TextBox CreateTextBox(int xPos,int yPos,Label label){
var input1 = new TextBox { Location = new Point(xPos, yPos)};
input1.TextChanged += new EventHandler((sender, e) => label.Visible = false);
return input1;
}
You just need to call the function in inputBox.Controls.Add method,and pass parameters which you need.
public static DialogResult ShowDialog()
{
var inputBox = new Form { ClientSize = new Size(520, 225), FormBorderStyle = FormBorderStyle.FixedDialog };
var label = new Label { Text = "Text", Location = new Point(25, 90), Visible = true };
inputBox.Controls.Add(CreateTextBox(25, 25,label));
inputBox.Controls.Add(CreateTextBox(25, 60,label));
inputBox.Controls.Add(label);
return inputBox.ShowDialog();
}
NOTE
if there are too many parameters you can try to use a class to carry those and pass.

ErrorProvider does not display error message

In the following code I used errorProvider.SetError(control, message) to display the message, but only the Icon is shown, the message is not shown, what is wrong?
Is there a way to adjust the left margin of the error message only? (I know you can SetIconPadding, but I only want left margin to be changed)
public static DialogResult ShowDialog()
{
var inputBox = new Form { ClientSize = new Size(520, 225), FormBorderStyle = FormBorderStyle.FixedDialog };
var panel = new TableLayoutPanel { Size = new Size(460, 100), Location = new System.Drawing.Point(45, 15) };
var errorProvider = new ErrorProvider { Icon = SystemIcons.Exclamation, BlinkStyle = ErrorBlinkStyle.NeverBlink };
errorProvider.SetIconAlignment(panel, ErrorIconAlignment.BottomLeft);
var okButton = new Button
{
Size = new System.Drawing.Size(70, 30),
Location = new Point(330, 180),
Text = "OK"
};
okButton.Click += new EventHandler((sender, e) => { errorProvider.SetError(panel, "Test Error"); });
inputBox.Controls.Add(panel);
inputBox.Controls.Add(okButton);
return inputBox.ShowDialog();
}
Let me explain about ErrorProvider.
ErrorProvider in Windows Application has following behaviour.
It will display error icon as per configuration.
It will display error message that you have set once you put your mouse cursor on it.
The behaviour you want is too display error message along with icon.
There is one solution build your own control just like ErrorProvider.

How can I show one user control and hide the rest in C#

I am new to C# and I am using windows forms.
I have Form1 with 20 buttons and 20 user controls. What I am trying to do is:
When I click button1 user control1 shows up and the rest of user controls hide, click button2 user control2 shows up and the rest of user controls hide, click button3 user control3 shows up and the rest of user controls hide and so on. I can use UserControl.visible = True to show one user control and hide the rest by setting the rest of user controls visibility = False but I do not want to write too much code.
So instead I used the following simple code to show only one user control at time when relevant button is clicked and hide the rest of user controls, but this code did not work it runs with no error but the user controls still visible .
Anyone knows why this code did not show one user control and hide the rest? I will be happy to hear other ideas too. Thank you
private void button1_Click(object sender, EventArgs e)
{
foreach (Control ctrl in this.Controls)
{
if (ctrl .GetType() == typeof(UserControl))
{
ctrl .Visible = false;
}
}
UserControl1.visible = True;
}
The reason your code is not working as expected is this condition:
if (ctrl.GetType() == typeof(UserControl))
GetType() returns the actual type which never will be UserControl, but some derived from it.
Use the following instead
if (ctrl is UserControl)
Button has a property Tag. Save your UserControl references in tag property for all buttons:
button1.Tag = UserControl1;
button2.Tag = UserControl2;
button3.Tag = UserControl3;
//and so on...
//you can do it FormLoad event handler
Now subscribe all buttons to single Click event:
button1.Click += button1_Click; //I am using "button1_Click" for all buttons
button2.Click += button1_Click;
button3.Click += button1_Click;
Now the main thing is here:
private void button1_Click(object sender, EventArgs e)
{
Button btn = sender as Button; //cast the sender
//hide all user controls
foreach (Control ctrl in this.Controls)
{
if (ctrl .GetType() == typeof(UserControl))
{
ctrl .Visible = false;
}
}
//show the usercontrol saved in "Tag" of the current button
(btn.Tag as UserControl).Visible = True;
}
Note: I have not compiled this code, if you get any error. Please let me know.
This code worked a treat for me:
var pairs = new[]
{
new { Button = button1, UserControl = userControl1 },
new { Button = button2, UserControl = userControl2 },
new { Button = button3, UserControl = userControl3 },
new { Button = button4, UserControl = userControl4 },
new { Button = button5, UserControl = userControl5 },
new { Button = button6, UserControl = userControl6 },
new { Button = button7, UserControl = userControl7 },
new { Button = button8, UserControl = userControl8 },
new { Button = button9, UserControl = userControl9 },
new { Button = button10, UserControl = userControl10 },
new { Button = button11, UserControl = userControl11 },
new { Button = button12, UserControl = userControl12 },
new { Button = button13, UserControl = userControl13 },
new { Button = button14, UserControl = userControl14 },
new { Button = button15, UserControl = userControl15 },
new { Button = button16, UserControl = userControl16 },
new { Button = button17, UserControl = userControl17 },
new { Button = button18, UserControl = userControl18 },
new { Button = button19, UserControl = userControl19 },
new { Button = button20, UserControl = userControl20 },
};
foreach (var pair in pairs)
{
pair.UserControl.Visible = false;
pair.Button.Click += (s, e2) =>
{
foreach (var pair2 in pairs) { pair2.UserControl.Visible = false; }
pair.UserControl.Visible = true;
};
}
I purposefully create a list of button/user control pairs so that they are hard-coded and I don't have to go looking for them by name. It's better this way for refactoring and verifying your code.
Then the first foreach loop just wires up the click event which makes all of the user controls invisible except for the paired user control.
Just pop this code in your Form_Load event handler.

Show WinFrm from C# console application and wait to close

I am trying to show a WinForm (inputbox) from a console application in C# and wait until the user closes the form. It is important for me to have the inputbox ontop and active when it opens. ShowDialog() is not working in my case as in some cases it does not appears as an active form. So I'd like to change my code and use Show(). This way I can manually make find out if the form is active or not and if not activate it myself. With ShowDialog(). my code stops and I can not do anything until the from is closed.
Below is my code. It does show the inputbox, however it is frozen. What am I doing wrong please? As clear the while-loop after "inputBox.Show();" is not doing anything, but if I can manage to run the loop and the inputbox does not freeze, I will sort out the rest myself. I appreciate your help.
public static string mInputBox(string strPrompt, string strTitle, string strDefaultResponse)
{
string strResponse = null;
Form inputBox = new Form();
inputBox.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
inputBox.ClientSize = new Size(500, 85);
inputBox.Text = strTitle;
inputBox.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
inputBox.Left = (Screen.PrimaryScreen.Bounds.Size.Width / 2) - (inputBox.ClientSize.Width / 2);
inputBox.Top = (Screen.PrimaryScreen.Bounds.Size.Height / 2) - (inputBox.ClientSize.Height / 2);
Label lblPrompt = new Label();
lblPrompt.Text = strPrompt;
inputBox.Controls.Add(lblPrompt);
TextBox textBox = new TextBox();
textBox.Text = strDefaultResponse;
inputBox.Controls.Add(textBox);
Button okButton = new Button();
okButton.Text = "&OK";
inputBox.Controls.Add(okButton);
Button cancelButton = new Button();
cancelButton.Text = "&Cancel";
inputBox.Controls.Add(cancelButton);
okButton.Click += (sender, e) =>
{
strResponse = textBox.Text;
inputBox.Close();
};
cancelButton.Click += (sender, e) =>
{
inputBox.Close();
};
inputBox.AcceptButton = okButton;
inputBox.CancelButton = cancelButton;
SetWindowPos(inputBox.Handle, HWND_TOPMOST, inputBox.Left, inputBox.Top, inputBox.Width, inputBox.Height, NOACTIVATE);
inputBox.Show();
while {true}
Thread.Sleep(100);
Application.DoEvents();
return strResponse;
}
I'm not sure why you are taking this route, I'm sure there are better ways to do it (explain one at the end). however to make your code run you should add Application.DoEvents() inside your loop
the code should be something like this:
var formActive = true;
inputBox.FormClosed += (s, e) => formActive = false;
inputBox.Show();
inputBox.TopMost = true;
inputBox.Activate();
while (formActive)
{
Thread.Sleep(10);
Application.DoEvents();
}
and the whole method will be:
public static string mInputBox(string strPrompt, string strTitle, string strDefaultResponse)
{
string strResponse = null;
Form inputBox = new Form();
inputBox.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
inputBox.ClientSize = new Size(500, 85);
inputBox.Text = strTitle;
inputBox.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
inputBox.Left = (Screen.PrimaryScreen.Bounds.Size.Width/2) - (inputBox.ClientSize.Width/2);
inputBox.Top = (Screen.PrimaryScreen.Bounds.Size.Height/2) - (inputBox.ClientSize.Height/2);
Label lblPrompt = new Label();
lblPrompt.Text = strPrompt;
inputBox.Controls.Add(lblPrompt);
TextBox textBox = new TextBox();
textBox.Text = strDefaultResponse;
inputBox.Controls.Add(textBox);
Button okButton = new Button();
okButton.Text = "&OK";
inputBox.Controls.Add(okButton);
Button cancelButton = new Button();
cancelButton.Text = "&Cancel";
inputBox.Controls.Add(cancelButton);
okButton.Click += (sender, e) =>
{
strResponse = textBox.Text;
inputBox.Close();
};
cancelButton.Click += (sender, e) =>
{
inputBox.Close();
};
inputBox.AcceptButton = okButton;
inputBox.CancelButton = cancelButton;
var formActive = true;
inputBox.FormClosed += (s, e) => formActive = false;
inputBox.Show();
inputBox.TopMost = true;
inputBox.Activate();
while (formActive)
{
Thread.Sleep(10);
Application.DoEvents();
}
return strResponse;
}
but I think it would be a better Idea to Derive from Form and create a InputBox and set TopMost and call Activate OnLoad to create what you need, then simply call ShowDialog, something like:
class Inputbox : Form
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
TopMost = true;
Activate();
}
}
and better to put UI code in InputBox class as the whole code and usage would be like:
class Inputbox : Form
{
public string Response { get; set; }
public Inputbox(string strTitle, string strPrompt, string strDefaultResponse)
{
//add UI and Controls here
FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
ClientSize = new Size(500, 85);
Text = strTitle;
StartPosition = System.Windows.Forms.FormStartPosition.Manual;
Left = (Screen.PrimaryScreen.Bounds.Size.Width/2) - (ClientSize.Width/2);
Top = (Screen.PrimaryScreen.Bounds.Size.Height/2) - (ClientSize.Height/2);
Label lblPrompt = new Label();
lblPrompt.Text = strPrompt;
Controls.Add(lblPrompt);
TextBox textBox = new TextBox();
textBox.Text = strDefaultResponse;
Controls.Add(textBox);
Button okButton = new Button();
okButton.Text = "&OK";
Controls.Add(okButton);
Button cancelButton = new Button();
cancelButton.Text = "&Cancel";
Controls.Add(cancelButton);
okButton.Click += (sender, e) =>
{
Response = textBox.Text;
Close();
};
cancelButton.Click += (sender, e) =>
{
Close();
};
AcceptButton = okButton;
CancelButton = cancelButton;
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
TopMost = true;
Activate();
}
}
public static string mInputBox(string strPrompt, string strTitle, string strDefaultResponse)
{
string strResponse = null;
Inputbox inputBox = new Inputbox(strPrompt,strTitle,strDefaultResponse);
inputBox.ShowDialog();
return inputBox.Response;
}
You need to run a message loop:
Application.Run(inputBox);

Categories

Resources