首页 > 解决方案 > 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'。

另一方面,在调试模式下,没有抛出这样的异常。所以,我有两个问题:

  1. 我想知道调试模式和发布模式有什么区别。
  2. 有什么方法可以避免抛出 System.TypeLoadException?

更新 1: 我已经在发布模式下配置了编译选项。

但是当我尝试构建我的项目时,它以以下错误消息结束:错误: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);
        }
    }

标签: windowsuwp

解决方案


我注意到您的问题已在 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>

推荐阅读