简体   繁体   English

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

[英]How to set Title for OpenFolderDialog in an Avalonia application?

I'm working with OpenFileDialog , SaveFileDialog and OpenFolderDialog in an Avalonia application.我正在 Avalonia 应用程序中使用OpenFileDialogSaveFileDialogOpenFolderDialog
One requirement is to set the title to a certain string.一个要求是将标题设置为某个字符串。
I achieved this for OpenFileDialog and SaveFileDialog but not for OpenFolderDialog .我为OpenFileDialogSaveFileDialog实现了这一点,但没有OpenFolderDialog
OpenFolderDialog resists applying the title, so that only a default title according the language of the operating system remains set. OpenFolderDialog拒绝应用标题,因此只有根据操作系统语言的默认标题保持设置。

I found that in ControlCatalogStandalone the OpenFolderDialog works correct, ie the title can be set as desired.我发现在ControlCatalogStandalone中, OpenFolderDialog工作正常,即可以根据需要设置标题。
So, I tried to reduce ControlCatalogStandalone to the Dialogs functionality and transform it to be as similar as possible to my test application.因此,我尝试将ControlCatalogStandalone简化为Dialogs功能,并将其转换为尽可能类似于我的测试应用程序。
I couldn't achieve that, but I found some clue that might help a more skilled developer to find the reason for the misbehavior of my test application.我无法做到这一点,但我发现了一些线索,可以帮助更熟练的开发人员找到我的测试应用程序行为不端的原因。

The Solution and the Project s of ControlCatalogStandalone are structured and composed much different to my Avalonia test application. ControlCatalogStandalone解决方案项目的结构和组成与我的 Avalonia 测试应用程序大不相同。
In my test application the target framework is .NET Core 3.1 .在我的测试应用程序中,目标框架是.NET Core 3.1
In one Project of the ControlCatalogStandalone Solution the target framework is .NET Standard 2.0 .ControlCatalogStandalone解决方案的一个项目中,目标框架是.NET Standard 2.0
So, I think OpenFolderDialog works correct in .NET Standard but not in .NET Core .所以,我认为OpenFolderDialog.NET Standard中工作正常,但在.NET Core中不正确。
I also think that if ControlCatalogStandalone was built from scratch with the current version of the Avalonia for Visual Studio Extension, it wouldn't produce a mix of frameworks.我还认为,如果ControlCatalogStandalone是使用当前版本的Avalonia for Visual Studio Extension 从头开始构建的,它不会产生混合框架。

Here are the relevant code parts of my test application:以下是我的测试应用程序的相关代码部分:

MainWindow.axaml: 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: 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.axaml.cs: 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);
        }
    }
}

I'm showing the last file because I wasn't able to implement the method Window GetWindow() => (Window)this.VisualRoot;我正在显示最后一个文件,因为我无法实现方法Window GetWindow() => (Window)this.VisualRoot; in my ViewModel which in ControlCatalogStandalone is implemented and used in the code behind of DialogsPage (which actually is a UserControl ).在我的 ViewModel 中,它在ControlCatalogStandalone中实现并用于DialogsPage背后的代码(实际上是一个UserControl )。
So, I implemented the Instance property which perhaps is a hack.所以,我实现了可能是 hack 的Instance属性。
If you also could give me hint on best practice to get the instance of the MainWindow I'd be happy.如果您也可以给我提示获取MainWindow实例的最佳实践,我会很高兴。

Is my problem not being able to set the title in OpenFolderDialog an open issue of the .NET Core implementation, or can you tell me how to get it working in my simple test application?我的问题是无法在OpenFolderDialog中设置标题是.NET Core实现的未解决问题,还是你能告诉我如何让它在我的简单测试应用程序中工作?

I'm not familiar/experienced with the Avalon framework so I won't comment too much on your different setup tests.我对 Avalon 框架并不熟悉/没有经验,因此我不会对您的不同设置测试发表过多评论。 However it seems that the OpenFolderDialog has a bug that it doesn't set the title when being showed, atleast for its Windows implementation.然而, OpenFolderDialog似乎有一个错误,它在显示时没有设置标题,至少对于它的Windows实现。 This is reported as a issue on the github source, and seems not yet solved:这被报告为 github 源上的问题,似乎尚未解决:

frm.SetTitle is missing for the folder dialog: Windows/Avalonia.Win32/SystemDialogImpl#L116文件夹对话框缺少 frm.SetTitle: Windows/Avalonia.Win32/SystemDialogImpl#L116

(In comparison to here for FileDialog). (与此处的 FileDialog 相比)。 Reference: https://github.com/AvaloniaUI/Avalonia/issues/3037参考: https://github.com/AvaloniaUI/Avalonia/issues/3037

Without further digging into the source, its unclear why the ControlCatalogStandalone example functions correctly since it appears to use the same method in #ShowAsync (used here ), which is defined here .在不进一步深入研究源代码的情况下,不清楚为什么ControlCatalogStandalone示例正常运行,因为它似乎在 #ShowAsync( 在此处使用)中使用相同的方法,该方法在此处定义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM