I'm working with OpenFileDialog
, SaveFileDialog
and OpenFolderDialog
in an Avalonia application.
One requirement is to set the title to a certain string.
I achieved this for OpenFileDialog
and SaveFileDialog
but not for OpenFolderDialog
.OpenFolderDialog
resists applying the title, so that only a default title according the language of the operating system remains set.
I found that in ControlCatalogStandalone the OpenFolderDialog
works correct, i.e. the title can be set as desired.
So, I tried to reduce ControlCatalogStandalone to the Dialogs functionality and transform it to be as similar as possible to my test application.
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 Projects of ControlCatalogStandalone are structured and composed much different to my Avalonia test application.
In my test application the target framework is .NET Core 3.1
.
In one Project of the ControlCatalogStandalone Solution the target framework is .NET Standard 2.0
.
So, I think OpenFolderDialog
works correct in .NET Standard
but not in .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.
Here are the relevant code parts of my test application:
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);
}
}
}
I'm showing the last file because I wasn't able to implement the method
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
).
So, I implemented the Instance
property which perhaps is a hack.
If you also could give me hint on best practice to get the instance of the MainWindow
I'd be happy.
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?
I'm not familiar/experienced with the Avalon framework so I won't comment too much on your different setup tests. However it seems that the OpenFolderDialog
has a bug that it doesn't set the title when being showed, atleast for its Windows implementation. This is reported as a issue on the github source, and seems not yet solved:
frm.SetTitle is missing for the folder dialog: Windows/Avalonia.Win32/SystemDialogImpl#L116
(In comparison to here for FileDialog). Reference: 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With