Reputation: 2275
I've got a WPF program and at some point I open a window:
public object testCommand()
{
Window window = new Window
{
Title = "My User Control Dialog",
Content = new OKMessageBox("Error Message"),
SizeToContent = SizeToContent.WidthAndHeight,
ResizeMode = ResizeMode.NoResize
};
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
window.ShowDialog();
return null;
}
User Control XAML:
<UserControl x:Class="SolidX.Base.MessageBoxes.OKMessageBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SolidX.Base.MessageBoxes"
xmlns:viewProperties="clr-namespace:AppResources.Properties;assembly=AppResources"
mc:Ignorable="d"
d:DesignHeight="150" d:DesignWidth="400">
<Grid>
<TextBlock x:Name="textMessage" Margin="10"/>
<Grid Height="Auto" VerticalAlignment="Bottom">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<CheckBox Content="Don't show this again" HorizontalAlignment="Right" Margin="5,5,10,5"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="btnOk" Content="{x:Static viewProperties:Resources.Common_OK}" Height="25" VerticalAlignment="Center" Width="90" Margin="5"/>
</StackPanel>
</Grid>
</Grid>
</UserControl>
User Control Code-behind:
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.Navigation;
using System.Windows.Shapes;
namespace SolidX.Base.MessageBoxes
{
/// <summary>
/// Interaction logic for OKMessageBox.xaml
/// </summary>
public partial class OKMessageBox : UserControl
{
public OKMessageBox(string Message)
{
InitializeComponent();
textMessage.Text= Message;
}
}
}
And in my user control, I am trying to have buttons that close the window (currently, setting Button.IsCancel = true;
works, but I want this to be a reusable option - essentially making my own this.Close;
).
I tried this (as suggested by a couple other StackOverflow answers) in the code-behind for my usercontrol but to no avail (parentWindow
is always null):
var parentWindow = Window.GetWindow(this);
parentWindow.Close();
Upvotes: 2
Views: 7144
Reputation: 11
None of those approaches worked for me. Most just closed the parent window. I was using an XAML Popup from my main window. Something like.
<DockPanel/>
<Popup x:Name="puMyControl"/>
<Local:UserControl />
</Popup>
</DockPanel>
Elsewhere in my main window code behind, I added:
puMyControl.IsOpen = true;
Inside the UserControl I had a cancel button. Popup's do not have children, therefore I needed to reference the Popup's parent which was the DockPanel.
private void BtnClose_Click(object sender, RoutedEventArgs e)
{
Popup pu = Parent as Popup;
if ( pu != null )
{
DockPanel dp = pu.Parent as DockPanel;
if (dp != null)
{
dp.Children.Remove(pu);
}
}
}
The aha moment was, that I was removing the Popup, not the UserControl. 'this' would refer to the UserControl. As you can see above, I am removing the Popup from the DockPanel. That led to a simpler and more universal solution.
Popup pu = Parent as Popup;
if (pu != null)
{
pu.IsOpen = false;
}
Upvotes: 0
Reputation: 1271
In case you are using ViewModel class for your Window
, you can set the ViewModel class to your Window
instance, and the ViewModel can store it's owner.
For example the ViewModel:
public class CloseConfirmViewModel
{
internal Window Owner { get; set; }
public ICommand CloseCommand { get; private set; } // ICommand to bind it to a Button
public CloseConfirmViewModel()
{
CloseCommand = new RelayCommand<object>(Close);
}
public void Close() // You can make it public in order to call it from codebehind
{
if (Owner == null)
return;
Owner.Close();
}
}
In order to get it work, you have to set the ViewModel class to your Window
:
public partial class CloseConfirmWindow : Window
{
public CloseConfirmWindow(CloseConfirmViewModel model)
{
DataContext = model;
InitializeComponent();
model.Owner = this;
}
}
And you are creating a new instance this way:
var model = new CloseConfirmViewModel();
var closeWindow = new CloseConfirmWindow(model);
closeWindow.ShowDialog(); // Hopefully you've added a button which has the ICommand binded
You can bind the Window
's CloseCommand
to the UserControl
's button this way, or if you are not using commands, call the Close()
method when the UC's button is being clicked.
Upvotes: 0
Reputation: 3877
To close modal dialog you should set DialogResult: DialogResult = false;
Upvotes: -1
Reputation: 1336
Try this in the UserControl:
xaml
<UserControl .... Loaded="UserControl_Loaded">
<!-- -->
</UserControl>
cs
public UserControl()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
var window = Window.GetWindow(this);
window.Close();
}
Upvotes: 6