【发布时间】:2011-07-08 19:16:39
【问题描述】:
我需要实现一个自定义窗口装饰器,其中 关闭 按钮的行为与所有 Windows 应用程序上的关闭或 x 按钮完全相同。
【问题讨论】:
标签: c# wpf button user-interface
我需要实现一个自定义窗口装饰器,其中 关闭 按钮的行为与所有 Windows 应用程序上的关闭或 x 按钮完全相同。
【问题讨论】:
标签: c# wpf button user-interface
只需从您的按钮调用close() 函数:
WPF:
<Button Name="CloseButton" Content="x" Click="CloseButton_Click" />
代码隐藏:
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Close();
}
【讨论】:
如果您想使用 MVVM 架构,则可以将窗口名称作为命令参数传递,并在命令中关闭窗口。
代码是这样的:
Button Command="{Binding MainCloseButtonCommand}"
CommandParameter="{Binding ElementName=mainWindow}"
private void performMainCloseButtonCommand(object Parameter)
{
Window objWindow = Parameter as Window;
objWindow.Close();
}
【讨论】:
如果你想要关闭对话框的按钮Window,你可以为他添加IsCancel属性:
<Button Name="CloseButton"
IsCancel="True" ... />
这表示以下MSDN:
当您将 Button 的
IsCancel属性设置为 true 时,您将创建一个向 AccessKeyManager 注册的 Button。 当用户按下 ESC 键时,按钮就会被激活。
现在,如果您单击此按钮,或按 Esc,则对话框 Window 正在关闭,但它不适用于普通的 MainWindow。
要关闭MainWindow,您可以简单地添加一个已经显示的 Click 处理程序。但是如果你想要一个更优雅的解决方案来满足 MVVM 风格,你可以添加以下 attached 行为:
public static class ButtonBehavior
{
#region Private Section
private static Window MainWindow = Application.Current.MainWindow;
#endregion
#region IsCloseProperty
public static readonly DependencyProperty IsCloseProperty;
public static void SetIsClose(DependencyObject DepObject, bool value)
{
DepObject.SetValue(IsCloseProperty, value);
}
public static bool GetIsClose(DependencyObject DepObject)
{
return (bool)DepObject.GetValue(IsCloseProperty);
}
static ButtonBehavior()
{
IsCloseProperty = DependencyProperty.RegisterAttached("IsClose",
typeof(bool),
typeof(ButtonBehavior),
new UIPropertyMetadata(false, IsCloseTurn));
}
#endregion
private static void IsCloseTurn(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is bool && ((bool)e.NewValue) == true)
{
if (MainWindow != null)
MainWindow.PreviewKeyDown += new KeyEventHandler(MainWindow_PreviewKeyDown);
var button = sender as Button;
if (button != null)
button.Click += new RoutedEventHandler(button_Click);
}
}
private static void button_Click(object sender, RoutedEventArgs e)
{
MainWindow.Close();
}
private static void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
MainWindow.Close();
}
}
在Window 中这样使用:
<Window x:Class="MyProjectNamespace.MainWindow"
xmlns:local="clr-namespace:MyProjectNamespace">
<Button Name="CloseButton"
local:ButtonBehavior.IsClose="True" ... />
现在MainWindow 可以通过单击按钮或按Esc 来关闭,这一切都独立于View (UI) 发生。
【讨论】:
如果您在当前视图中添加一个按钮,让我们从后面的代码中说:
var closeButton = new Button();
closeButton.Click += closeButton_Click;
// Add the button to the window
Content = closeButton;
然后你就可以响应事件并像这样调用Close():
void closeButton_Click(object sender, RoutedEventArgs e)
{
Close();
}
这基本上是在您的Window / UserControl 添加一个按钮,当您按下它时,它将关闭窗口。
如果您从 XAML 执行此操作,它可能如下所示:
<Button Name="closeButton" Click="closeButton_Click" />
【讨论】:
其实是这样的:
<Window Name = "Chrome">
.
.
<Button Name="closeButton" onClick="terminateApplication"/>
.
</Window>
在 CS 文件中,
private void terminateApplication(object sender, RoutedEventArgs e)
{
Chrome.Close();
}
【讨论】:
在视图模型中使用关闭按钮。查看模型不依赖于 gui。
namespace YourLibrary.ComponentModel
{
/// <summary>
/// Defines Close method. Use for window, file stream,....
/// </summary>
public interface IClosable
{
/// <summary>
/// Close of instance (window, file stream,... etc).
/// </summary>
void Close();
}
}
MyWindow.xaml
<Window ...
x:Name="ThisInstance"
...
>
<Button Command="{Binding ButtonCommand}" CommandParameter="{Binding ElementName=ThisInstance}">
MyWindow.xaml.cs
public partial class MyWindow : Window, YourLibrary.ComponentModel.IClosable
{
....
}
MyViewModel.cs
public class MyViewModel
{
ICommand buttonCommand;
/// <summary>
/// Command for Button.
/// Default action is close the window.
/// Close window via retyping parameter as <see cref="IClosable"/>
/// </summary>
public ICommand ButtonCommand => buttonCommand ?? (buttonCommand=new RelayCommand(ButtonCommandExecute));
void ButtonCommandExecute (object obj)
{
var myWindow = (IClosable)obj;
myWindow.Close();
};
测试,在控制台中使用视图模型
class Program
{
public class ConsoleWindow : YourLibrary.ComponentModel.IClosable
{
public void Close()
{
Console.WriteLine("Closing area...");
}
}
static void Main(string[] args)
{
var program = new Program();
program.DoMain(args);
}
public void DoMain(string[] args)
{
var consoleWindow = new ConsoleWindow();
var viewModel = new MyViewModel()
viewModel.ButtonCommand.Execute(consoleWindow);
}
}
【讨论】: