You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在UWP中如何通过自定义按钮触发标题栏的最小化/最大化/关闭操作?

UWP自定义按钮模拟标题栏最小化、最大化、关闭操作的实现方案

当然可以实现该功能。UWP没有WPF的SystemCommands类,但可以通过ApplicationView(窗口状态控制)和CoreApplication(窗口/应用关闭)的原生API直接实现对应操作,以下是分场景的详细实现步骤:

核心依赖命名空间

首先确保代码文件中引用以下命名空间:

using Windows.ApplicationModel.Core;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml.Navigation;

一、基础实现(代码后台绑定点击事件)

1. 最小化窗口

XAML按钮定义:

<Button Content="最小化" Click="MinimizeButton_Click" Margin="4" />

后台点击事件处理:

private async void MinimizeButton_Click(object sender, RoutedEventArgs e)
{
    // 仅在桌面环境下执行(移动端无窗口概念)
    if (ApplicationView.GetForCurrentView().WindowingEnvironment == WindowingEnvironment.Desktop)
    {
        // TryMinimizeAsync支持Windows 10 1607及以上版本,兼容性覆盖绝大多数设备
        await ApplicationView.GetForCurrentView().TryMinimizeAsync();
    }
}

2. 最大化/还原窗口(支持状态切换)

XAML按钮定义(命名用于状态同步):

<Button x:Name="MaxRestoreBtn" Content="最大化" Click="MaxRestoreBtn_Click" Margin="4" />

后台点击事件处理:

private async void MaxRestoreBtn_Click(object sender, RoutedEventArgs e)
{
    var currentView = ApplicationView.GetForCurrentView();
    if (currentView.WindowingEnvironment != WindowingEnvironment.Desktop) return;

    // 先退出全屏模式(如果当前是全屏)
    if (currentView.IsFullScreenMode)
    {
        await currentView.ExitFullScreenModeAsync();
    }

    // 根据当前状态切换最大化/还原
    if (currentView.IsMaximized)
    {
        await currentView.TryRestoreAsync();
        MaxRestoreBtn.Content = "最大化";
    }
    else
    {
        await currentView.TryMaximizeAsync();
        MaxRestoreBtn.Content = "还原";
    }
}

状态同步优化:当用户通过系统标题栏改变窗口状态时,同步自定义按钮的显示文本,在页面导航事件中注册监听:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    ApplicationView.GetForCurrentView().VisibleBoundsChanged += CurrentView_VisibleBoundsChanged;
    UpdateMaxRestoreBtnText();
}

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);
    ApplicationView.GetForCurrentView().VisibleBoundsChanged -= CurrentView_VisibleBoundsChanged;
}

private void CurrentView_VisibleBoundsChanged(ApplicationView sender, object args)
{
    UpdateMaxRestoreBtnText();
}

private void UpdateMaxRestoreBtnText()
{
    MaxRestoreBtn.Content = ApplicationView.GetForCurrentView().IsMaximized ? "还原" : "最大化";
}

3. 关闭窗口/应用

XAML按钮定义:

<Button Content="关闭" Click="CloseButton_Click" Margin="4" />

后台点击事件处理(两种场景可选):

private void CloseButton_Click(object sender, RoutedEventArgs e)
{
    // 场景1:仅关闭当前窗口(多窗口应用适用)
    CoreApplication.GetCurrentView().CoreWindow.Close();

    // 场景2:直接退出整个应用(单窗口应用常用)
    // Application.Current.Exit();
}

二、MVVM模式实现(命令绑定)

如果采用MVVM架构,可通过自定义RelayCommand实现命令绑定,避免代码后台的事件耦合:

1. 实现基础RelayCommand类

public class RelayCommand : ICommand
{
    private readonly Action _execute;
    private readonly Func<bool> _canExecute;

    public RelayCommand(Action execute, Func<bool> canExecute = null)
    {
        _execute = execute ?? throw new ArgumentNullException(nameof(execute));
        _canExecute = canExecute;
    }

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter) => _canExecute?.Invoke() ?? true;

    public void Execute(object parameter) => _execute();

    public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}

2. ViewModel定义命令与状态属性

public class MainViewModel : INotifyPropertyChanged
{
    public ICommand MinimizeCommand { get; }
    public ICommand MaxRestoreCommand { get; }
    public ICommand CloseCommand { get; }

    private bool _isMaximized;
    public bool IsMaximized
    {
        get => _isMaximized;
        set
        {
            _isMaximized = value;
            OnPropertyChanged();
        }
    }

    public MainViewModel()
    {
        // 最小化命令
        MinimizeCommand = new RelayCommand(async () =>
        {
            if (ApplicationView.GetForCurrentView().WindowingEnvironment == WindowingEnvironment.Desktop)
            {
                await ApplicationView.GetForCurrentView().TryMinimizeAsync();
            }
        });

        // 最大化/还原命令
        MaxRestoreCommand = new RelayCommand(async () =>
        {
            var currentView = ApplicationView.GetForCurrentView();
            if (currentView.WindowingEnvironment != WindowingEnvironment.Desktop) return;

            if (currentView.IsFullScreenMode)
                await currentView.ExitFullScreenModeAsync();

            if (currentView.IsMaximized)
                await currentView.TryRestoreAsync();
            else
                await currentView.TryMaximizeAsync();

            // 更新状态属性
            IsMaximized = currentView.IsMaximized;
        });

        // 关闭命令
        CloseCommand = new RelayCommand(() => CoreApplication.GetCurrentView().CoreWindow.Close());

        // 监听窗口状态变化,同步IsMaximized属性
        ApplicationView.GetForCurrentView().VisibleBoundsChanged += (s, e) =>
        {
            IsMaximized = ApplicationView.GetForCurrentView().IsMaximized;
        };
    }

    // 实现INotifyPropertyChanged接口
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

3. XAML绑定与转换器

首先实现布尔值转文本的转换器:

public class BoolToMaxRestoreTextConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return (bool)value ? "还原" : "最大化";
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

在页面资源中声明转换器并绑定ViewModel:

<Page.Resources>
    <local:BoolToMaxRestoreTextConverter x:Key="BoolToMaxRestoreTextConverter" />
</Page.Resources>

<Page.DataContext>
    <local:MainViewModel />
</Page.DataContext>

<!-- 按钮绑定 -->
<Button Content="最小化" Command="{Binding MinimizeCommand}" Margin="4" />
<Button Content="{Binding IsMaximized, Converter={StaticResource BoolToMaxRestoreTextConverter}}" 
        Command="{Binding MaxRestoreCommand}" Margin="4" />
<Button Content="关闭" Command="{Binding CloseCommand}" Margin="4" />

三、关键注意事项

  • 设备兼容性:所有窗口控制API仅在桌面版Windows 10/11上有效,移动端UWP无窗口概念,调用前建议通过WindowingEnvironment.Desktop判断环境。
  • 异步处理:TryMinimizeAsync、TryMaximizeAsync等方法为异步操作,需用await调用避免UI线程阻塞。
  • 多窗口场景:ApplicationView.GetForCurrentView()获取的是当前激活窗口的视图,确保操作目标正确。

内容的提问来源于stack exchange,提问作者ricky rocky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 11:39:50