簡體   English   中英

如何在 Avalonia 應用程序中為 OpenFolderDialog 設置標題?

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

我正在 Avalonia 應用程序中使用OpenFileDialogSaveFileDialogOpenFolderDialog
一個要求是將標題設置為某個字符串。
我為OpenFileDialogSaveFileDialog實現了這一點,但沒有OpenFolderDialog
OpenFolderDialog拒絕應用標題,因此只有根據操作系統語言的默認標題保持設置。

我發現在ControlCatalogStandalone中, OpenFolderDialog工作正常,即可以根據需要設置標題。
因此,我嘗試將ControlCatalogStandalone簡化為Dialogs功能,並將其轉換為盡可能類似於我的測試應用程序。
我無法做到這一點,但我發現了一些線索,可以幫助更熟練的開發人員找到我的測試應用程序行為不端的原因。

ControlCatalogStandalone解決方案項目的結構和組成與我的 Avalonia 測試應用程序大不相同。
在我的測試應用程序中,目標框架是.NET Core 3.1
ControlCatalogStandalone解決方案的一個項目中,目標框架是.NET Standard 2.0
所以,我認為OpenFolderDialog.NET Standard中工作正常,但在.NET Core中不正確。
我還認為,如果ControlCatalogStandalone是使用當前版本的Avalonia for Visual Studio Extension 從頭開始構建的,它不會產生混合框架。

以下是我的測試應用程序的相關代碼部分:

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

我正在顯示最后一個文件,因為我無法實現方法Window GetWindow() => (Window)this.VisualRoot; 在我的 ViewModel 中,它在ControlCatalogStandalone中實現並用於DialogsPage背后的代碼(實際上是一個UserControl )。
所以,我實現了可能是 hack 的Instance屬性。
如果您也可以給我提示獲取MainWindow實例的最佳實踐,我會很高興。

我的問題是無法在OpenFolderDialog中設置標題是.NET Core實現的未解決問題,還是你能告訴我如何讓它在我的簡單測試應用程序中工作?

我對 Avalon 框架並不熟悉/沒有經驗,因此我不會對您的不同設置測試發表過多評論。 然而, OpenFolderDialog似乎有一個錯誤,它在顯示時沒有設置標題,至少對於它的Windows實現。 這被報告為 github 源上的問題,似乎尚未解決:

文件夾對話框缺少 frm.SetTitle: Windows/Avalonia.Win32/SystemDialogImpl#L116

(與此處的 FileDialog 相比)。 參考: https://github.com/AvaloniaUI/Avalonia/issues/3037

在不進一步深入研究源代碼的情況下,不清楚為什么ControlCatalogStandalone示例正常運行,因為它似乎在 #ShowAsync( 在此處使用)中使用相同的方法,該方法在此處定義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM