windows - Microsoft.Xaml.Interactivity 中发生 System.TypeLoadException
问题描述
我正在尝试在我的 UWP 应用程序中使用 Microsoft.Xaml.Interactivity 在 ListView 中附加一个事件处理程序。当我在 ListView 中选择一行时,应用程序会根据所选项目执行一个过程。
因此,我安装了“Microsoft.Xaml.Behaviors.Uwp.Managed”包并更改了一个 XAML 文件,如下所示:
<ListView VerticalAlignment="Stretch"
x:Name="listBoxobj"
HorizontalAlignment="Stretch"
Margin="10,0,0,10"
Background="White"
Foreground="Black"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Tools}"
SelectedItem= "{Binding SelectedItem, Mode=Twoway}"
SelectionMode="Single">
<Interactivity:Interaction.Behaviors>
<Interactions:EventTriggerBehavior EventName="ItemClick" SourceObject="listBoxObj">
<Interactions:InvokeCommandAction Command="{Binding Tool_Clicked}" CommandParameter="{Binding SelectedItem}" />
</Interactions:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
并在其 ViewModel 中实现了以下内容:
private System.Windows.Input.ICommand tool_Clicked;
public ICommand Tool_Clicked
{
get {
return tool_Clicked;
}
set {
if (!Object.ReferenceEquals(tool_Clicked, value))
{
tool_Clicked = value as RelayCommand;
OnPropertyChanged("Tool_Clicked");
}
}
}
public DisplayViewModel()
{
...
Tool_Clicked = new RelayCommand(SelectionChanged);
...
}
public void SelectionChanged(object arg) {
... executes some procedures according to the selected item...
}
但是当我测试这些代码时,发出了以下异常:System.TypeLoadException:'找不到 Windows 运行时类型'System.Windows.Input.ICommand'。
另一方面,在调试模式下,没有抛出这样的异常。所以,我有两个问题:
- 我想知道调试模式和发布模式有什么区别。
- 有什么方法可以避免抛出 System.TypeLoadException?
更新 1: 我已经在发布模式下配置了编译选项。
- 我检查了“使用 .NET 本机工具链编译”
- 我检查了“不安全代码”。
但是当我尝试构建我的项目时,它以以下错误消息结束:错误:MCG0018:TypeExpected Type File or assembly 'System.Runtime.InteropServices.WindowsRuntime.PropertyType' not found。
当我尝试取消选中“使用 .NET 本机工具链编译”时,我可以运行此代码。我认为我使用的一些 nuget 包不支持 .NET 本机代码......
更新 2:
我制作了 RelayCommand 类,如下所示:
public class RelayCommand : ICommand
{
private readonly Action<Object> _execute;
private readonly Func<object, bool> _canExecute;
public event EventHandler CanExecuteChanged;
public RelayCommand(Action<object> execute) :
this(execute, null)
{ }
public RelayCommand(Action<object> execute, Func<object, bool> canExecute)
{
_execute = execute ?? throw new ArgumentNullException("execute");
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
解决方案
我注意到您的问题已在 Microsoft 问答中得到解决 - System.TypeLoadException 发生在Nico 的发布模式中。
为了使 Nico 的回答简短,您可以使用Tapped
事件而不是使用click
事件。然后你可以使用当前的数据上下文作为参数
像这样的代码:
<DataTemplate>
<TextBlock Text="{Binding}">
<Interactivity:Interaction.Behaviors>
<Interactions:EventTriggerBehavior EventName="Tapped">
<Interactions:InvokeCommandAction Command="{Binding ElementName=listBoxObj, Path=DataContext.Tool_Clicked}" CommandParameter="{Binding}" />
</Interactions:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</TextBlock>
</DataTemplate>
推荐阅读
- reactjs - 如何用 jest 测试 combineReducers
- kubernetes - k8s 究竟是如何为命名空间预留资源的?
- angular - 构建 Angular 7 库时如何修复 Name Expected 错误?
- javascript - 正确填充 Angular 响应式表单
- css - 如何在 TouchableOpacity 中插入文本和图像?
- python - twinx 网格线的可见性
- r - igraph - 获取在两个顶点之间形成路径的所有边 - 有更好的解决方案吗?
- mysql - 如何在 TEMPORARY 表上使用多个 IN 条件进行选择?
- python-3.x - Python fonttools:检查字体是否支持多代码点表情符号
- mysql - 订单数据冗余