Visibility of 2 user component in Silverlight - silverlight

In my application got one sidebar, which is holding this two component :
<Grid x:Name="AF" Visibility="Visibility">
<betata:AForm Height="508" VerticalAlignment="Top"/>
</Grid>
<Grid x:Name="AR" Visibility="Collapsed">
<betata:AReg Height="508" VerticalAlignment="Top"/>
</Grid>
in the AForm got hyperlink button with this method :
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
betata.Views.Sidebar.Sidebar sd = new Sidebar();
sd.showAR(this);
}
back to my sidebar code got another method called showAR with these function :
public void showAR(AForm aForm)
{
this.AR.Visibility = Visibility.Visible;
aForm.Visibility = Visibility.Collapsed;
}
but i not sure why the aForm will collapsed but AR could not become visible.

I would refactor this a bit, to make it more simple (which might help to solve your problem).
<Grid>
<betat:AForm x:Name="aForm" Height="508" VerticalAlignment="Top" Visibility="Visible" />
<betata:AReg x:Name="aReg" Height="508" VerticalAlignment="Top" Visibility="Collapsed" />
</Grid>
public void showAR() // this is in the code behind (xaml.cs) of the Sidebar UserControl
{
this.aReg.Visibility = Visibility.Visible;
this.aForm.Visibility = Visibility.Collapsed;
}
or you don't even need the ShowAR() and could just set the visibility in the button click, unless you're reusing the function in other places.Example:
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
betata.Views.Sidebar.Sidebar sd = new Sidebar();
sd.aReg.Visibility = Visibility.Visible;
sd.aForm.Visibility = Visibility.Collapsed;
}

Question had been answer in this post. Visibility of User Control can be solve via tunnelling and bubbling. which are new routing events function of silverlight

Related

How can i change visibility of a grid declared in another class after successful login

I have a class X and it has some buttons which are hidden under a grid . One of the button which is visible on double click opens the login pop up (declared in Y class) . Now after the successful login I would like to make grid hidden (because buttons are behind that grid).
how can i make grid declared in X class Hidden after successful login in Y class.
class X code:
<Grid Background="Black" x:Name="smallAGrid" x:FieldModifier="public"
Opacity="0.8" Grid.Column="1" Visibility="Visible" />
<Grid Background="Black" x:Name="bigBGrid" x:FieldModifier="public"
Opacity="0.8" Grid.Column="1" Grid.ColumnSpan="2" Visibility="Visible"/>
<Grid Name="ModeGrid" >
<Button Content="Gateway" Height="42" x:Name="maintenanceMode"
Width="148" Click="maintenanceMode_Click"/>
<Popup Placement="Center" x:Name="passwordProtectionPopUp"
AllowsTransparency="True">
<Grid>
<local:Y Width="350" Height="Auto" Margin="0,0,0,0" />
</Grid>
</Popup>
</Grid>
class Y code:
private void Submit_Click(object sender, RoutedEventArgs e)
{
try
{
if (sqlCon.State == System.Data.ConnectionState.Closed)
sqlCon.Open();
//rest of the login code here
}
// after Successful login i would like to do
X x = new X();
x.smallAGrid.Visibility = Visibility.Hidden;
}
catch
{
}
Note:But Iam unable to change the visibility .After putting breakpoint , I checked it goes to my X class and this visibility function but it doesn't change it ???
Assuming you have class X representing a parent window and class Y representing login window, you could use something similar to:
Class X
{
Control grid; //grid which you want to show/hide
Button btnLogin; //button which opens up login window
public void BtnLogin_DoubleClicked(object sender, EventArgs args)
{
var loginWindow = new Y(LoginSuccessCallback, LoginFailureCallback);
loginWindow.ShowDialog();
}
private void LoginSuccessCallback()
{
grid.Visibility = Visibility.Collapsed;
}
private void LoginFailureCallback()
{
grid.Visibility = Visibility.Visible;
}
}
found answer Its pretty simple Just declare control you want to access as static in the original class and assign them to the original control names and in other class where you want to access do this:
y class code
private void Submit_Click(object sender, RoutedEventArgs e)
{
try
{
if (sqlCon.State == System.Data.ConnectionState.Closed)
sqlCon.Open();
//rest of the login code here
Grid vr= X.small;
vr.Visibility = Visibility.Collapsed;
}
catch
{
}
X Class code
public static Grid small;
public X()
{
InitializeComponent();
small= smallAGrid // (name of grid control)
}

How can I place one control in a callout that orginates from another control in XAML?

Here is a setup: I have a textbox with a numberic value. According to the requirements every time anybody changes that value an accompanying comment needs to be provided. So visually there must be another textbox for the comment that should be displayed right next to the first one. Ideally the comment textbox needs to be placed in a callout that originates from the value textbox and displayed on the right from it overlaying anything what's underneath of it just like on this picture:
I know how to do easily it in CSS and HTML.
I have to do the same in Silverlight now.
Unfortunately I am not very strong in it, so what I am specifically asking about is how having 2 textboxes make one of them appear next to another (on the right overlaying whatever controls are underneath it) with as less XAML and code as possible.
Use a ToolTip, and set the Placement such that it appears to the right. in XAML, you can template your ToolTip to look however you want, even if that means mimicking the TextBox appearance.
This is the purpose of the ToolTip, and I feel strongly that you should always use the right tool for the right job. :)
I hope this helps. Let us know if you need code samples.
EDIT: Added the following code samples:
<TextBox ToolTipService.Placement="Right">
<ToolTipService.ToolTip>
<TextBox Text="{Binding CalloutText, Mode=OneWay}" IsReadOnly="True"/>
</ToolTipService.ToolTip>
</TextBox>
Ok, I ended up writing my own behaviour
namespace MyNamespace
{
public class CommentBehavior : Behavior<TextBox>
{
private readonly TimeSpan howLongWeWaitBeforePopupCloses = TimeSpan.FromMilliseconds(200);
private DispatcherTimer popupClosingTimer;
public static DependencyProperty PopupProperty = DependencyProperty.Register("Popup", typeof(Popup), typeof(CommentBehavior), new PropertyMetadata(null));
public Popup Popup
{
get { return (Popup)this.GetValue(PopupProperty); }
set { this.SetValue(PopupProperty, value); }
}
protected override void OnAttached()
{
this.popupClosingTimer = new DispatcherTimer();
this.popupClosingTimer.Stop();
this.popupClosingTimer.Interval = howLongWeWaitBeforePopupCloses;
this.popupClosingTimer.Tick += this.ClosePopup;
this.AssociatedObject.GotFocus += this.GotFocus;
this.AssociatedObject.LostFocus += this.LostFocus;
this.Popup.Child.GotFocus += PopupChild_GotFocus;
this.Popup.Child.LostFocus += PopupChild_LostFocus;
}
private void PopupChild_LostFocus(object sender, RoutedEventArgs e)
{
this.popupClosingTimer.Start();
}
private void PopupChild_GotFocus(object sender, RoutedEventArgs e)
{
this.popupClosingTimer.Stop();
}
protected override void OnDetaching()
{
this.AssociatedObject.GotFocus -= this.GotFocus;
this.AssociatedObject.LostFocus -= this.LostFocus;
this.Popup.GotFocus -= PopupChild_GotFocus;
this.popupClosingTimer.Tick -= this.ClosePopup;
this.popupClosingTimer = null;
}
private void ClosePopup(object sender, EventArgs e)
{
this.Popup.IsOpen = false;
this.popupClosingTimer.Stop();
}
protected void GotFocus(object sender, RoutedEventArgs e)
{
this.popupClosingTimer.Stop();
this.Popup.IsOpen = true;
var at = this.CalculatePopupPosition();
this.Popup.HorizontalOffset = at.X;
this.Popup.VerticalOffset = at.Y;
}
private Point CalculatePopupPosition()
{
var owner = this.AssociatedObject;
var transformation = owner.TransformToVisual(Application.Current.RootVisual);
var at = transformation.Transform(new Point(owner.ActualWidth, 0));
return at;
}
protected void LostFocus(object sender, RoutedEventArgs e)
{
this.popupClosingTimer.Start();
}
}
}
And the following XAML
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Background="Red">
<TextBox Width="200" Text="0.01">
<i:Interaction.Behaviors>
<local:CommentBehavior>
<local:CommentBehavior.Popup>
<Popup>
<TextBox Text="Comment" />
</Popup>
</local:CommentBehavior.Popup>
</local:CommentBehavior>
</i:Interaction.Behaviors>
</TextBox>
</StackPanel>
</Grid>

how to add mp3 songs to the listbox using wpf?

I have Music folder in my solution explorer..then i want to add that songs to the list box control after that i want to play the selected songs from listbox in the media element using wpf?
Please Help me.
Thanks
To make play behaviour eexplici on a button click , refer this:
Xaml :
<MediaElement x:Name="media" Source="{Binding
ElementName=listbox,Path=SelectedItem}"
LoadedBehavior="Manual" UnloadedBehavior="Manual"/>
<Button Click="Button_Click" Height="27" VerticalAlignment="Bottom"
HorizontalAlignment="Left" Width="62">Play</Button>
Code Behind :-
private void Button_Click (object sender, RoutedEventArgs e) {
media.Play ();
}
You should implement business logic to browse the directory you are targetting. Prepare a collection of Items. Bind these to Listbox
For playing the song, bind selected item to MediaElement.
I will try to compile some simple solution and update if you still need further help.
Updating simple solution:
Xaml:
<StackPanel Orientation="Vertical">
<ListBox ItemsSource="{Binding}" x:Name="fileList"></ListBox>
<MediaElement x:Name="mediaElement" Source="{Binding ElementName=fileList, Path=SelectedItem}"/>
</StackPanel>
Code Behind:
public partial class Window1 : Window {
ObservableCollection<string> mFileList;
public Window1 () {
InitializeComponent ();
GetFiles(#"..\songs");
this.DataContext = mFileList;
}
private void GetFiles (string folderPath) {
string[] files = Directory.GetFiles(folderPath);
mFileList = new ObservableCollection<string> (files);
}
}
You need to handle the mediaended event as below :-
<MediaElement x:Name="media" Source="{Binding ElementName=listbox,Path=SelectedItem}" MediaEnded="media_MediaEnded"
></MediaElement>
Codebehind :-
` private void media_MediaEnded (object sender, RoutedEventArgs e) {
if (listbox.SelectedIndex < listbox.Items.Count - 1) {
listbox.SelectedIndex = listbox.SelectedIndex + 1;
}`
You need to handle the mediaended event as below :-
<MediaElement x:Name="media" Source="{Binding ElementName=listbox,Path=SelectedItem}" Margin="0,119,78,64" MediaEnded="media_MediaEnded"
></MediaElement>
private void media_MediaEnded (object sender, RoutedEventArgs e) {
if (listbox.SelectedIndex < listbox.Items.Count - 1) {
listbox.SelectedIndex = listbox.SelectedIndex + 1;
}
}

How to update Source property of a frame by clicking only one button from user control?

I’d like to find out about how to update a source property by clicking only one "Next" button based on a click count and being able to load different pages into frame each time the button is clicked another time. Any advice is highly appreciated! Thank you in advance.
Main Window Code:
<Grid x:Name="LayoutRoot">
<Frame Content="Frame" Source="/WpfApplication1;component/Page1.xaml"/>
<local:NavUserControl HorizontalAlignment="Center" VerticalAlignment="Bottom"/>
</Grid>
User control that contains the button:
<StackPanel x:Name="LayoutRoot" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,20">
<Button Content="Back" HorizontalAlignment="Left" Width="75"/>
<Button Content="Next" HorizontalAlignment="Left" Width="75" />
</StackPanel>
Create a PageViewModel class that implements NextPageCommand and PreviousPageCommand commands, which raise (respectively) UserNavigatedToNextPage and UserNavigatedToPreviousPage events. To make it simple, also have them expose NextPage and PreviousPage properties of type PageViewModel. Create subclasses of PageViewModel for each page.
Create a view model class for the owning UserControl that exposes a CurrentPage property of type PageViewModel. Create all of the PageViewModel objects and set NextPage and PreviousPage on each. Add handlers for the navigation events on these object that look something like:
public void Page_UserNavigatedToNextPage(object sender, EventArgs e)
{
if (sender == CurrentPage && CurrentPage.NextPage != null)
{
CurrentPage = CurrentPage.NextPage;
}
}
Assuming that you've implemented property-change notification, now whenever the current page's NextPageCommand or PreviousPageCommand executes, the CurrentPage property will be updated and will be reflected in the UI. If you've created a data template for each page view model type, all you need is
<ContentPresenter Content="{Binding CurrentPage}"/>
in your user control and you're good to go.
If the Next/Previous buttons are in your control, and not in the page, then implement properties in the main view model that expose CurrentPage.NextPageCommand and CurrentPage.PreviousPageCommand, and bind the buttons to them.
In your NavUserControl, I would wire up either events or commands (or both, perhaps) for the next and back buttons. Then you can access those from within the MainWindow and set the appropriate value into the Source property.
If you go the event route, attach onto the events and set the Source directly.
If you go the command route, setup a command in your viewmodel, bind it to the usercontrol, and bind the Source property to another value in your viewmodel.
Edit: Adding some code per the OP's request. Keep in mind, this is not intended to be best practices. Just some examples.
To go the event route should be the simplest. You already know how to do this, I'd imagine. Just add:
public event EventHandler BackClicked;
public event EventHandler NextClicked;
private void Back_Click(object sender, RoutedEventArgs e)
{
BackClicked(sender, e);
}
private void Next_Click(object sender, RoutedEventArgs e)
{
NextClicked(sender, e);
}
events to your NavUserControl. Then change your XAML to:
<StackPanel x:Name="LayoutRoot" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,20">
<Button Content="Back" HorizontalAlignment="Left" Width="75" Click="Back_Click" />
<Button Content="Next" HorizontalAlignment="Left" Width="75" Click="Next_Click" />
</StackPanel>
And now in your MainWindow.xaml.cs file, add:
private void BackClicked(object sender, EventArgs e)
{
Uri source = // Whatever your business logic is to determine the previous page;
_Frame.Source = source;
}
private void NextClicked(object sender, EventArgs e)
{
Uri source = // Whatever your business logic is to determine the next page;
_Frame.Source = source;
}
and change the MainWindow XAML to be:
<Grid x:Name="LayoutRoot">
<Frame x:Name="_Frame" Content="Frame"
Source="/WpfApplication1;component/Page1.xaml"/>
<local:NavUserControl HorizontalAlignment="Center" VerticalAlignment="Bottom"
BackClicked="BackClicked" NextClicked="NextClicked" />
</Grid>
Going the command route takes a little more architecting, but is a lot more clean. I'd recommend using your favorite MVVM toolkit. My favorite is MVVMLight, so that's what I'll use for this example.
Create a ViewModel class, something like this:
public class ViewModel : GalaSoft.MvvmLight.ViewModelBase
{
private Uri _Source;
public Uri Source
{
get { return _Source; }
set
{
if (_Source != value)
{
_Source = value;
RaisePropertyChanged("Source");
}
}
}
private GalaSoft.MvvmLight.Command.RelayCommand _BackCommand;
public ICommand BackCommand
{
get
{
if (_BackCommand == null)
{
_BackCommand = new GalaSoft.MvvmLight.Command.RelayCommand(() =>
{
Uri source = // Whatever your business logic is to determine the previous page
Source = source;
});
}
return _BackCommand;
}
}
private GalaSoft.MvvmLight.Command.RelayCommand _NextCommand;
public ICommand NextCommand
{
get
{
if (_NextCommand == null)
{
_NextCommand = new GalaSoft.MvvmLight.Command.RelayCommand(() =>
{
Uri source = // Whatever your business logic is to determine the next page
Source = source;
});
}
return _NextCommand;
}
}
}
In your MainWindow.xaml.cs, create an instance of this class and set your DataContext property to that instance. Then setup your bindings:
<Grid x:Name="LayoutRoot">
<Frame Content="Frame" Source="{Binding Source}"/>
<local:NavUserControl HorizontalAlignment="Center" VerticalAlignment="Bottom"/>
</Grid>
and
<StackPanel x:Name="LayoutRoot" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,20">
<Button Content="Back" HorizontalAlignment="Left" Width="75" Command="{Binding BackCommand}"/>
<Button Content="Next" HorizontalAlignment="Left" Width="75" Command="{Binding NextCommand}" />
</StackPanel>
The binding example is pretty straight-forward MVVM-style WPF. I'd suggest you go that route and if you need more help, go read up on MVVM in WPF. Lots of resources out there in the form of tutorials and books. Searching here on SO can help a lot as well.
Edit again:
Change your constructor to this:
public MainWindow()
{
this.InitializeComponent();
// Insert code required on object creation below this point.
DataContext = new ViewModel();
}

WPF: Create a dialog / prompt

I need to create a Dialog / Prompt including TextBox for user input. My problem is, how to get the text after having confirmed the dialog? Usually I would make a class for this which would save the text in a property. However I want do design the Dialog using XAML. So I would somehow have to extent the XAML Code to save the content of the TextBox in a property - but I guess that's not possible with pure XAML. What would be the best way to realize what I'd like to do? How to build a dialog which can be defined from XAML but can still somehow return the input? Thanks for any hint!
The "responsible" answer would be for me to suggest building a ViewModel for the dialog and use two-way databinding on the TextBox so that the ViewModel had some "ResponseText" property or what not. This is easy enough to do but probably overkill.
The pragmatic answer would be to just give your text box an x:Name so that it becomes a member and expose the text as a property in your code behind class like so:
<!-- Incredibly simplified XAML -->
<Window x:Class="MyDialog">
<StackPanel>
<TextBlock Text="Enter some text" />
<TextBox x:Name="ResponseTextBox" />
<Button Content="OK" Click="OKButton_Click" />
</StackPanel>
</Window>
Then in your code behind...
partial class MyDialog : Window {
public MyDialog() {
InitializeComponent();
}
public string ResponseText {
get { return ResponseTextBox.Text; }
set { ResponseTextBox.Text = value; }
}
private void OKButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
DialogResult = true;
}
}
Then to use it...
var dialog = new MyDialog();
if (dialog.ShowDialog() == true) {
MessageBox.Show("You said: " + dialog.ResponseText);
}
Edit: Can be installed with nuget https://www.nuget.org/packages/PromptDialog/
I just add a static method to call it like a MessageBox:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
x:Class="utils.PromptDialog"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStartupLocation="CenterScreen"
SizeToContent="WidthAndHeight"
MinWidth="300"
MinHeight="100"
WindowStyle="SingleBorderWindow"
ResizeMode="CanMinimize">
<StackPanel Margin="5">
<TextBlock Name="txtQuestion" Margin="5"/>
<TextBox Name="txtResponse" Margin="5"/>
<PasswordBox Name="txtPasswordResponse" />
<StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right">
<Button Content="_Ok" IsDefault="True" Margin="5" Name="btnOk" Click="btnOk_Click" />
<Button Content="_Cancel" IsCancel="True" Margin="5" Name="btnCancel" Click="btnCancel_Click" />
</StackPanel>
</StackPanel>
</Window>
And the code behind:
public partial class PromptDialog : Window
{
public enum InputType
{
Text,
Password
}
private InputType _inputType = InputType.Text;
public PromptDialog(string question, string title, string defaultValue = "", InputType inputType = InputType.Text)
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(PromptDialog_Loaded);
txtQuestion.Text = question;
Title = title;
txtResponse.Text = defaultValue;
_inputType = inputType;
if (_inputType == InputType.Password)
txtResponse.Visibility = Visibility.Collapsed;
else
txtPasswordResponse.Visibility = Visibility.Collapsed;
}
void PromptDialog_Loaded(object sender, RoutedEventArgs e)
{
if (_inputType == InputType.Password)
txtPasswordResponse.Focus();
else
txtResponse.Focus();
}
public static string Prompt(string question, string title, string defaultValue = "", InputType inputType = InputType.Text)
{
PromptDialog inst = new PromptDialog(question, title, defaultValue, inputType);
inst.ShowDialog();
if (inst.DialogResult == true)
return inst.ResponseText;
return null;
}
public string ResponseText
{
get
{
if (_inputType == InputType.Password)
return txtPasswordResponse.Password;
else
return txtResponse.Text;
}
}
private void btnOk_Click(object sender, RoutedEventArgs e)
{
DialogResult = true;
Close();
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
Close();
}
}
So you can call it like:
string repeatPassword = PromptDialog.Prompt("Repeat password", "Password confirm", inputType: PromptDialog.InputType.Password);
Great answer of Josh, all credit to him, I slightly modified it to this however:
MyDialog Xaml
<StackPanel Margin="5,5,5,5">
<TextBlock Name="TitleTextBox" Margin="0,0,0,10" />
<TextBox Name="InputTextBox" Padding="3,3,3,3" />
<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Name="BtnOk" Content="OK" Grid.Column="0" Margin="0,0,5,0" Padding="8" Click="BtnOk_Click" />
<Button Name="BtnCancel" Content="Cancel" Grid.Column="1" Margin="5,0,0,0" Padding="8" Click="BtnCancel_Click" />
</Grid>
</StackPanel>
MyDialog Code Behind
public MyDialog()
{
InitializeComponent();
}
public MyDialog(string title,string input)
{
InitializeComponent();
TitleText = title;
InputText = input;
}
public string TitleText
{
get { return TitleTextBox.Text; }
set { TitleTextBox.Text = value; }
}
public string InputText
{
get { return InputTextBox.Text; }
set { InputTextBox.Text = value; }
}
public bool Canceled { get; set; }
private void BtnCancel_Click(object sender, System.Windows.RoutedEventArgs e)
{
Canceled = true;
Close();
}
private void BtnOk_Click(object sender, System.Windows.RoutedEventArgs e)
{
Canceled = false;
Close();
}
And call it somewhere else
var dialog = new MyDialog("test", "hello");
dialog.Show();
dialog.Closing += (sender,e) =>
{
var d = sender as MyDialog;
if(!d.Canceled)
MessageBox.Show(d.InputText);
}
You don't need ANY of these other fancy answers. Below is a simplistic example that doesn't have all the Margin, Height, Width properties set in the XAML, but should be enough to show how to get this done at a basic level.
XAML
Build a Window page like you would normally and add your fields to it, say a Label and TextBox control inside a StackPanel:
<StackPanel Orientation="Horizontal">
<Label Name="lblUser" Content="User Name:" />
<TextBox Name="txtUser" />
</StackPanel>
Then create a standard Button for Submission ("OK" or "Submit") and a "Cancel" button if you like:
<StackPanel Orientation="Horizontal">
<Button Name="btnSubmit" Click="btnSubmit_Click" Content="Submit" />
<Button Name="btnCancel" Click="btnCancel_Click" Content="Cancel" />
</StackPanel>
Code-Behind
You'll add the Click event handler functions in the code-behind, but when you go there, first, declare a public variable where you will store your textbox value:
public static string strUserName = String.Empty;
Then, for the event handler functions (right-click the Click function on the button XAML, select "Go To Definition", it will create it for you), you need a check to see if your box is empty. You store it in your variable if it is not, and close your window:
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
if (!String.IsNullOrEmpty(txtUser.Text))
{
strUserName = txtUser.Text;
this.Close();
}
else
MessageBox.Show("Must provide a user name in the textbox.");
}
Calling It From Another Page
You're thinking, if I close my window with that this.Close() up there, my value is gone, right? NO!! I found this out from another site: http://www.dreamincode.net/forums/topic/359208-wpf-how-to-make-simple-popup-window-for-input/
They had a similar example to this (I cleaned it up a bit) of how to open your Window from another and retrieve the values:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnOpenPopup_Click(object sender, RoutedEventArgs e)
{
MyPopupWindow popup = new MyPopupWindow(); // this is the class of your other page
//ShowDialog means you can't focus the parent window, only the popup
popup.ShowDialog(); //execution will block here in this method until the popup closes
string result = popup.strUserName;
UserNameTextBlock.Text = result; // should show what was input on the other page
}
}
Cancel Button
You're thinking, well what about that Cancel button, though? So we just add another public variable back in our pop-up window code-behind:
public static bool cancelled = false;
And let's include our btnCancel_Click event handler, and make one change to btnSubmit_Click:
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
cancelled = true;
strUserName = String.Empty;
this.Close();
}
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
if (!String.IsNullOrEmpty(txtUser.Text))
{
strUserName = txtUser.Text;
cancelled = false; // <-- I add this in here, just in case
this.Close();
}
else
MessageBox.Show("Must provide a user name in the textbox.");
}
And then we just read that variable in our MainWindow btnOpenPopup_Click event:
private void btnOpenPopup_Click(object sender, RoutedEventArgs e)
{
MyPopupWindow popup = new MyPopupWindow(); // this is the class of your other page
//ShowDialog means you can't focus the parent window, only the popup
popup.ShowDialog(); //execution will block here in this method until the popup closes
// **Here we find out if we cancelled or not**
if (popup.cancelled == true)
return;
else
{
string result = popup.strUserName;
UserNameTextBlock.Text = result; // should show what was input on the other page
}
}
Long response, but I wanted to show how easy this is using public static variables. No DialogResult, no returning values, nothing. Just open the window, store your values with the button events in the pop-up window, then retrieve them afterwards in the main window function.

Resources