我目前正在研究 Avalonia,想要构建可重复使用的控件,可以在我的最终应用程序的多个地方使用。
为了简单起见,我想要一个UserControl
名为的FilePicker
,它只是一个Button
。单击后,应打开一个文件选择器对话框(此代码不是我的问题的一部分)。
使用的控件FilePicker
应该绑定到选定的文件并对其执行任何操作。
我从当前开始,Avalonia template in Visual Studio 2022
最终形成如下文件夹结构:
这FilePicker.axaml
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:userControls="clr-namespace:FoodShiner.Avalonia.UserControls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="FoodShiner.Avalonia.UserControls.FilePicker"
x:DataType="userControls:FilePickerViewModel">
<Button Command="{Binding OpenFileDialog}">Test</Button>
</UserControl>
隐藏代码FilePicker.axaml.cs
:
using Avalonia.Controls;
namespace FoodShiner.Avalonia.UserControls;
public partial class FilePicker : UserControl
{
public FilePicker()
{
InitializeComponent();
}
}
和视图模型FilePickerViewModel.cs
:
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
using FoodShiner.Avalonia.ViewModels;
namespace FoodShiner.Avalonia.UserControls
{
internal partial class FilePickerViewModel : ViewModelBase
{
[RelayCommand]
public async Task OpenFileDialog()
{
}
}
}
编译、构建和运行没有任何问题,显示了名为 的按钮Test
。一旦点击,我得到
尝试通过方法“CompiledAvaloniaXaml.XamlIlTrampolines.FoodShiner.Avalonia:FoodShiner.Avalonia.UserControls.FilePickerViewModel+OpenFileDialog_0!CommandExecuteTrampoline(System.Object, System.Object)”访问方法“FoodShiner.Avalonia.UserControls.FilePickerViewModel.OpenFileDialog()”失败。
public
因此我将绑定命令的修饰符更改为
System.InvalidCastException:“无法将类型为‘FoodShiner.Avalonia.ViewModels.MainViewModel’的对象转换为类型‘FoodShiner.Avalonia.UserControls.FilePickerViewModel’。”
我开始觉得我的整个概念都是错的,这不是解决问题的办法。另一方面,通过构建可重用控件似乎是一件“简单”的事情。我还尝试了一个专用库(可能会以 nuget 的形式发布),但这个也失败了。
另一方面,他们AavaloniaUI
无法为我提供一些关于如何做到这一点的有用示例。XAML、WPF 或 CommunityToolkit 都没有帮助。由于我现在已经是 blazor-dev 了,这似乎更加复杂,因为 blazor 中的概念有点不同
以下是其他文件(可能有帮助)
MainView.axaml
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:FoodShiner.Avalonia.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="FoodShiner.Avalonia.Views.MainView"
x:DataType="vm:MainViewModel">
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:MainViewModel />
</Design.DataContext>
</UserControl>
和`MainWindow.axaml
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:uc="using:FoodShiner.Avalonia.UserControls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="FoodShiner.Avalonia.Views.MainWindow"
Icon="/Assets/avalonia-logo.ico"
Title="FoodShiner.Avalonia"
RequestedThemeVariant="Dark"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center">
<uc:FilePicker />
</Window>
CommunityToolkit.Mvvm的 [ RelayCommand ]属性将为您生成一个
IAsyncRelayCommand
名为OpenFileDialogCommand 。因此,下面的代码应该可以工作: