如何在 Avalonia 应用程序中设置 OpenFolderDialog 的标题?

Zol*_*dan 8 c# avaloniaui avalonia

我正在使用OpenFileDialog,SaveFileDialogOpenFolderDialog在 Avalonia 应用程序中工作。
一个要求是将标题设置为特定字符串。
我实现了这一点OpenFileDialogSaveFileDialog不是为了OpenFolderDialog
OpenFolderDialog拒绝应用标题,因此仅保留根据操作系统语言设置的默认标题。

我发现在ControlCatalogStandalone中工作OpenFolderDialog正常,即标题可以根据需要设置。
因此,我尝试将ControlCatalogStandalone简化为对话框功能,并将其转换为与我的测试应用程序尽可能相似。
我无法实现这一点,但我发现了一些线索,可以帮助技术更熟练的开发人员找到我的测试应用程序行为不当的原因。ControlCatalogStandalone解决方案

和项目结构和组成与我的 Avalonia 测试应用程序有很大不同。 在我的测试应用程序中,目标框架是. 在ControlCatalogStandalone解决方案 的一个项目中,目标框架是. 所以,我认为在 中工作正确,但在. 我还认为,如果ControlCatalogStandalone是使用当前版本的扩展从头开始构建的,它不会产生框架的混合。 以下是我的测试应用程序的相关代码部分: MainWindow.axaml:
.NET Core 3.1
.NET Standard 2.0
OpenFolderDialog.NET Standard.NET Core
Avalonia for Visual Studio



<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:DialogTests.ViewModels;assembly=DialogTests"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" Width="200" Height="150"
        x:Class="DialogTests.Views.MainWindow"
        Icon="/Assets/avalonia-logo.ico"
        Title="DialogTests">

    <Design.DataContext>
        <vm:MainWindowViewModel/>
    </Design.DataContext>

    <Grid RowDefinitions="*,*,*">
        <Button Grid.Column="0" Grid.Row="0" Command="{Binding OpenFileDialogCommand}" Content="OpenFileDialog"/>
        <Button Grid.Column="0" Grid.Row="1" Command="{Binding SaveFileDialogCommand}" Content="SaveFileDialog"/>
        <Button Grid.Column="0" Grid.Row="2" Command="{Binding OpenFolderDialogCommand}" Content="OpenFolderDialog"/>
    </Grid>

</Window>
Run Code Online (Sandbox Code Playgroud)

MainWindowViewModel.cs:

using Avalonia.Controls;
using DialogTests.Views;
using ReactiveUI;
using System.Collections.Generic;
using System.Reactive;

namespace DialogTests.ViewModels
{
    public class MainWindowViewModel : ViewModelBase
    {
        public MainWindowViewModel()
        {
            OpenFileDialogCommand = ReactiveCommand.Create(() => {
                new OpenFileDialog()
                {
                    Title = "Open File Dialog",
                    Filters = GetFilters()
                }.ShowAsync(MainWindow.Instance);
            });

            SaveFileDialogCommand = ReactiveCommand.Create(() =>
            {
                new SaveFileDialog()
                {
                    Title = "Save File Dialog",
                    Filters = GetFilters()
                }.ShowAsync(MainWindow.Instance);
            });

            OpenFolderDialogCommand = ReactiveCommand.Create(() => {
                new OpenFolderDialog()
                {
                    Title = "Open Folder Dialog"
                }.ShowAsync(MainWindow.Instance);
            });
        }

        public ReactiveCommand<Unit, Unit> OpenFileDialogCommand { get; }
        public ReactiveCommand<Unit, Unit> SaveFileDialogCommand { get; }
        public ReactiveCommand<Unit, Unit> OpenFolderDialogCommand { get; }

        List<FileDialogFilter> GetFilters()
        {
            return new List<FileDialogFilter>
                {
                    new FileDialogFilter
                    {
                        Name = "Text files", Extensions = new List<string> {"txt"}
                    },
                    new FileDialogFilter
                    {
                        Name = "All files",
                        Extensions = new List<string> {"*"}
                    }
                };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

MainWindow.axaml.cs:

using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;

namespace DialogTests.Views
{
    public class MainWindow : Window
    {
        public static MainWindow Instance { get; private set; }
        public MainWindow()
        {
            Instance = this;
            InitializeComponent();
#if DEBUG
            this.AttachDevTools();
#endif
        }

        private void InitializeComponent()
        {
            AvaloniaXamlLoader.Load(this);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我显示最后一个文件是因为我无法 Window GetWindow() => (Window)this.VisualRoot;在 ViewModel 中实现该方法,该方法在ControlCatalogStandalone中实现并在后面的代码中使用DialogsPage(实际上是一个UserControl)。
所以,我实现了这个Instance可能是黑客的属性。
如果您还可以给我有关获得实例的最佳实践的提示,MainWindow我会很高兴。

我的问题是无法在OpenFolderDialog实现的未决问题中设置标题.NET Core,或者您能告诉我如何让它在我的简单测试应用程序中工作吗?

Ben*_*Ben 1

我对 Avalon 框架不熟悉/没有经验,所以我不会对您的不同设置测试发表太多评论。然而,似乎OpenFolderDialog有一个错误,它在显示时没有设置标题,至少对于它的Windows实现来说是这样。这是 github 源代码中的一个问题,似乎尚未解决:

文件夹对话框缺少 frm.SetTitle: Windows/Avalonia.Win32/SystemDialogImpl#L116

(与此处的 FileDialog相比)。参考: https: //github.com/AvaloniaUI/Avalonia/issues/3037

如果不进一步深入研究源代码,就不清楚为什么该示例能够正确运行,因为它似乎在#ShowAsync(此处ControlCatalogStandalone使用)中使用了相同的方法,该方法在此处定义。