【问题标题】:How to set Title for OpenFolderDialog in an Avalonia application?如何在 Avalonia 应用程序中为 OpenFolderDialog 设置标题?
【发布时间】:2020-11-29 01:27:03
【问题描述】:

我正在使用 Avalonia 应用程序中的 OpenFileDialogSaveFileDialogOpenFolderDialog
一项要求是将标题设置为某个字符串。
我为 OpenFileDialogSaveFileDialog 实现了这一点,但 notOpenFolderDialog
OpenFolderDialog 拒绝应用标题,因此只保留了根据操作系统语言的默认标题设置。

我发现在ControlCatalogStandaloneOpenFolderDialog 工作正常,即可以根据需要设置标题。
因此,我尝试将 ControlCatalogStandalone 简化为 Dialogs 功能,并将其转换为尽可能类似于我的测试应用程序。
我无法做到这一点,但我发现了一些线索,可以帮助更熟练的开发人员找到我的测试应用程序行为不端的原因。

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

以下是我的测试应用程序的相关代码部分:

MainWindow.axaml:

<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>

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> {"*"}
                    }
                };
        }
    }
}

MainWindow.asaml.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);
        }
    }
}

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

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

【问题讨论】:

    标签: c# avaloniaui avalonia


    【解决方案1】:

    我不熟悉/不熟悉 Avalon 框架,因此我不会对您的不同设置测试发表过多评论。然而,OpenFolderDialog 似乎有一个错误,它在显示时没有设置标题,至少对于它的 Windows 实现。这被报告为 github 源上的一个问题,似乎尚未解决:

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

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

    没有进一步挖掘源代码,不清楚为什么ControlCatalogStandalone 示例正常运行,因为它似乎在#ShowAsync 中使用相同的方法(使用here),它被定义为here

    【讨论】:

    • 你说得对,这是框架中的一个错误。我认为它适用于 ControlCatalog 示例,因为他们在那里使用自定义样式的文件夹选择器对话框,不是吗?
    • 我正在对此问题进行更多调查,以清楚地显示 OpenFolderDialog 在 ControlCatalogStandalone 应用程序和我自己的测试应用程序中的不同行为。我已经上传了我的测试应用程序和 ControlCatalogStandalone 应用程序的全部源代码,我将其简化为对话框功能,但现在我认为它们不再需要了。感谢大家的信息,感谢您新创建的问题。
    猜你喜欢
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    • 2022-07-28
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多