如何从用户控件里面关闭一个window?
How to close a window from the user control inside?
我有一个 WPF 程序,有时我打开一个 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;
}
用户控制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>
用户控制代码隐藏:
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;
}
}
}
并且在我的用户控件中,我尝试使用关闭 window 的按钮(目前,设置 Button.IsCancel = true;
有效,但我希望这是一个可重复使用的选项 - 本质上是我自己的this.Close;
).
我在我的用户控件的代码隐藏中尝试了这个(正如其他几个 Whosebug 答案所建议的那样)但无济于事(parentWindow
始终为 null):
var parentWindow = Window.GetWindow(this);
parentWindow.Close();
如果您为您的 Window
使用 ViewModel class,您可以将 ViewModel class 设置为您的 Window
实例,并且 ViewModel 可以存储它的所有者.
例如 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();
}
}
为了使其正常工作,您必须将 ViewModel class 设置为您的 Window
:
public partial class CloseConfirmWindow : Window
{
public CloseConfirmWindow(CloseConfirmViewModel model)
{
DataContext = model;
InitializeComponent();
model.Owner = this;
}
}
并且您正在以这种方式创建一个新实例:
var model = new CloseConfirmViewModel();
var closeWindow = new CloseConfirmWindow(model);
closeWindow.ShowDialog(); // Hopefully you've added a button which has the ICommand binded
您可以通过这种方式将 Window
的 CloseCommand
绑定到 UserControl
的按钮,或者如果您不使用命令,请调用 Close()
方法当点击 UC 的按钮时。
在用户控件中试试这个:
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();
}
要关闭模式对话框,您应该设置 DialogResult: DialogResult = false;
None 这些方法对我有用。大多数只是关闭父 window。我使用的是主 window 中的 XAML 弹出窗口。有点像。
<DockPanel/>
<Popup x:Name="puMyControl"/>
<Local:UserControl />
</Popup>
</DockPanel>
在我后面的主要 window 代码的其他地方,我添加了:
puMyControl.IsOpen = true;
我在 UserControl 中有一个取消按钮。 Popup 没有子项,因此我需要引用 Popup 的父项,即 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);
}
}
}
突然想到,我要删除的是 Popup,而不是 UserControl。 'this' 将引用 UserControl。正如您在上面看到的,我正在从 DockPanel 中删除 Popup。这导致了一个更简单、更通用的解决方案。
Popup pu = Parent as Popup;
if (pu != null)
{
pu.IsOpen = false;
}
我有一个 WPF 程序,有时我打开一个 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;
}
用户控制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>
用户控制代码隐藏:
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;
}
}
}
并且在我的用户控件中,我尝试使用关闭 window 的按钮(目前,设置 Button.IsCancel = true;
有效,但我希望这是一个可重复使用的选项 - 本质上是我自己的this.Close;
).
我在我的用户控件的代码隐藏中尝试了这个(正如其他几个 Whosebug 答案所建议的那样)但无济于事(parentWindow
始终为 null):
var parentWindow = Window.GetWindow(this);
parentWindow.Close();
如果您为您的 Window
使用 ViewModel class,您可以将 ViewModel class 设置为您的 Window
实例,并且 ViewModel 可以存储它的所有者.
例如 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();
}
}
为了使其正常工作,您必须将 ViewModel class 设置为您的 Window
:
public partial class CloseConfirmWindow : Window
{
public CloseConfirmWindow(CloseConfirmViewModel model)
{
DataContext = model;
InitializeComponent();
model.Owner = this;
}
}
并且您正在以这种方式创建一个新实例:
var model = new CloseConfirmViewModel();
var closeWindow = new CloseConfirmWindow(model);
closeWindow.ShowDialog(); // Hopefully you've added a button which has the ICommand binded
您可以通过这种方式将 Window
的 CloseCommand
绑定到 UserControl
的按钮,或者如果您不使用命令,请调用 Close()
方法当点击 UC 的按钮时。
在用户控件中试试这个:
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();
}
要关闭模式对话框,您应该设置 DialogResult: DialogResult = false;
None 这些方法对我有用。大多数只是关闭父 window。我使用的是主 window 中的 XAML 弹出窗口。有点像。
<DockPanel/>
<Popup x:Name="puMyControl"/>
<Local:UserControl />
</Popup>
</DockPanel>
在我后面的主要 window 代码的其他地方,我添加了:
puMyControl.IsOpen = true;
我在 UserControl 中有一个取消按钮。 Popup 没有子项,因此我需要引用 Popup 的父项,即 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);
}
}
}
突然想到,我要删除的是 Popup,而不是 UserControl。 'this' 将引用 UserControl。正如您在上面看到的,我正在从 DockPanel 中删除 Popup。这导致了一个更简单、更通用的解决方案。
Popup pu = Parent as Popup;
if (pu != null)
{
pu.IsOpen = false;
}