如何在 Avalonia 应用程序中设置 OpenFolderDialog 的标题?
How to set Title for OpenFolderDialog in an Avalonia application?
我正在 Avalonia 应用程序中使用 OpenFileDialog
、SaveFileDialog
和 OpenFolderDialog
。
一个要求是将标题设置为某个字符串。
我为 OpenFileDialog
和 SaveFileDialog
实现了这一点,但 而不是 为 OpenFolderDialog
.
OpenFolderDialog
拒绝应用标题,因此仅保留根据操作系统语言设置的默认标题。
我发现在 ControlCatalogStandalone 中 OpenFolderDialog
工作正常,即标题可以根据需要设置。
因此,我尝试将 ControlCatalogStandalone 减少为 Dialogs 功能,并将其转换为尽可能与我的测试应用程序相似。
我无法做到这一点,但我发现了一些线索,可以帮助更熟练的开发人员找到我的测试应用程序行为不当的原因。
ControlCatalogStandalone 的 Solution 和 Project 的结构和组成与我的 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.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
)。
所以,我实现了 Instance
属性 这可能是一个 hack。
如果您还可以给我提示有关获取 MainWindow
实例的最佳实践,我会很高兴。
我无法在 OpenFolderDialog
中设置标题的问题是 .NET Core
实现的未解决问题,还是您能告诉我如何让它在我的简单测试应用程序中工作?
我 familiar/experienced 不熟悉 Avalon 框架,所以我不会对您的不同设置测试发表太多评论。然而,OpenFolderDialog
似乎有一个错误,它在显示时没有设置标题,至少对于它的 Windows 实现。这是 github 来源上的一个问题,似乎尚未解决:
frm.SetTitle is missing for the folder dialog:
Windows/Avalonia.Win32/SystemDialogImpl#L116
(与 FileDialog 的 here 相比)。
参考:https://github.com/AvaloniaUI/Avalonia/issues/3037
在不进一步深入研究源代码的情况下,不清楚为什么 ControlCatalogStandalone
示例可以正常运行,因为它似乎在 #ShowAsync 中使用了相同的方法(使用 here), which is defined here.
我正在 Avalonia 应用程序中使用 OpenFileDialog
、SaveFileDialog
和 OpenFolderDialog
。
一个要求是将标题设置为某个字符串。
我为 OpenFileDialog
和 SaveFileDialog
实现了这一点,但 而不是 为 OpenFolderDialog
.
OpenFolderDialog
拒绝应用标题,因此仅保留根据操作系统语言设置的默认标题。
我发现在 ControlCatalogStandalone 中 OpenFolderDialog
工作正常,即标题可以根据需要设置。
因此,我尝试将 ControlCatalogStandalone 减少为 Dialogs 功能,并将其转换为尽可能与我的测试应用程序相似。
我无法做到这一点,但我发现了一些线索,可以帮助更熟练的开发人员找到我的测试应用程序行为不当的原因。
ControlCatalogStandalone 的 Solution 和 Project 的结构和组成与我的 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.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
)。
所以,我实现了 Instance
属性 这可能是一个 hack。
如果您还可以给我提示有关获取 MainWindow
实例的最佳实践,我会很高兴。
我无法在 OpenFolderDialog
中设置标题的问题是 .NET Core
实现的未解决问题,还是您能告诉我如何让它在我的简单测试应用程序中工作?
我 familiar/experienced 不熟悉 Avalon 框架,所以我不会对您的不同设置测试发表太多评论。然而,OpenFolderDialog
似乎有一个错误,它在显示时没有设置标题,至少对于它的 Windows 实现。这是 github 来源上的一个问题,似乎尚未解决:
frm.SetTitle is missing for the folder dialog: Windows/Avalonia.Win32/SystemDialogImpl#L116
(与 FileDialog 的 here 相比)。 参考:https://github.com/AvaloniaUI/Avalonia/issues/3037
在不进一步深入研究源代码的情况下,不清楚为什么 ControlCatalogStandalone
示例可以正常运行,因为它似乎在 #ShowAsync 中使用了相同的方法(使用 here), which is defined here.