【问题标题】:listview selecteditem as T command paramenter when event is Tapped gives a type cast exception当事件被点击时,listview selecteditem 作为 T 命令参数给出类型转换异常
【发布时间】:2020-03-09 14:57:15
【问题描述】:

我有一个绑定到集合的 ListView,即 List<InnerGridItems> 在我的例子中。问题是当我尝试将 SelectedItem 绑定到 CommandParameter 时,有时它会给出一个类型转换异常,指出无法从 Windows.UI.TappedEventArgs 类型转换到 InnerGridItems。 (WPF 和 UWP 的概念相同,有一个 Click 事件,所以我添加 WPF 标签)。请帮忙。

Xaml:

<ListView Margin="0,10,0,0" x:Name="lstInnerItems" Grid.Row="1" 
          ItemsSource="{Binding InnerBarCodeItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
          SelectionMode="Single"
          HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
          Tag="{Binding ElementName=ImgFlash}">
     <Interactivity:Interaction.Behaviors>
         <Core:EventTriggerBehavior EventName="Tapped">
             <Core:InvokeCommandAction 
                   Command="{Binding ListSelectionChangedCommand,Mode=OneWay}" 
                   CommandParameter="{Binding ElementName=lstInnerItems, Path=SelectedItem}"></Core:InvokeCommandAction>
         </Core:EventTriggerBehavior>
     </Interactivity:Interaction.Behaviors>
     <ListView.ItemTemplate>
         <DataTemplate>
              <StackPanel Orientation="Horizontal">
                  <RadioButton x:Name="rbnEnumerated" GroupName="A" 
                               IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                      <Interactivity:Interaction.Behaviors>
                          <Core:DataTriggerBehavior Binding="{Binding IsVisible, Mode=TwoWay}" Value="False">
                              <Core:ChangePropertyAction TargetObject="{Binding ElementName=rbnEnumerated}" PropertyName="Visibility" Value="Collapsed" />
                          </Core:DataTriggerBehavior>
                          <Core:DataTriggerBehavior Binding="{Binding IsVisible, Mode=TwoWay}" Value="True">
                              <Core:ChangePropertyAction TargetObject="{Binding ElementName=rbnEnumerated}" PropertyName="Visibility" Value="Visible" />
                          </Core:DataTriggerBehavior>
                      </Interactivity:Interaction.Behaviors>
                  </RadioButton>
                  <TextBlock Text="{Binding SerialNumber}" Margin="10,0,0,0"></TextBlock>
                  <TextBlock Margin="14,0,0,0">
                      <Run Text="("></Run>
                      <Run Text="{Binding SerialPort}"></Run>
                      <Run Text=")"></Run>
                  </TextBlock>
              </StackPanel>
          </DataTemplate>
      </ListView.ItemTemplate>
  </ListView>

这是我的模型类

InnerGridItems.cs

public class InnerGridItems : BindableBaseThreadSafe
    {
        private string _serialNumber = "N/A";
        public string SerialNumber
        {
            get => _serialNumber;
            set => Set(ref _serialNumber, value);
        }
        private string _serialPort = "N/A";
        public string SerialPort
        {
            get => _serialPort;
            set => Set(ref _serialPort, value);
        }
        private bool _isChecked;
        public bool IsChecked
        {
            get => _isChecked;
            set => Set(ref _isChecked, value);
        }
        private MemoryStream _flashedBarCodeImage;
        public MemoryStream FlashedBarCodeImage
        {
            get => _flashedBarCodeImage;
            set => Set(ref _flashedBarCodeImage, value);
        }
        private bool _isVisisble = true;
        public bool IsVisible
        {
            get => _isVisisble;
            set => Set(ref _isVisisble, value);
        }

    }

这是我的 ICommand

public ICommand ListSelectionChangedCommand { get; set; }
 private void FlashImageForSelectedRow(InnerGridItems obj)
        {
         //Gives an exception that it cannot type cast to InnerGridItems.
        }

【问题讨论】:

    标签: c# wpf uwp command


    【解决方案1】:

    如果这是一个间歇性问题,您可以尝试在使用 isas 运算符/关键字执行转换之前检查转换,或者捕获异常。 as 更好,因为它的演员阵容更少(Is versus as discussion

    使用as

    var items = eventArgs as InnerGridItems;
    if(items != null)
    {
        //do stuff with items!
    }
    else
    {
         //do nothing, or whatever you want to handle this condition
    }
    
    

    使用is

    if( eventArgs is InnerGridItems)
    { 
        var items = eventArgs as InnerGridItems;
        //do stuff with items!
    }
    else // this could allow you to do multiple is checks.
    {
         //do nothing, or whatever you want to handle this condition
    }
    

    然后您将更改您的FlashImageForSelectedRow 方法以接受objectEventArgs 实例,然后在该方法内部执行as / is 检查。

    这并不能回答为什么会发生这种情况的更深层次的问题,似乎点击事件有时无法获取您的 InnerGridItems 实例。 除非深入了解问题对您来说真的很重要(这非常酷,请分享您发现的任何内容!),我认为添加一个简单的检查可能就足够了,并且可以让您将时间花在其他事情上!

    【讨论】:

    • 是的,你是对的。我什至尝试在 xaml.cs 中引发手动 Tapped 事件,并且 SelectedItem 是 InnerGridItems。这会间歇性发生。
    • 列表视图中的项目是否始终如一地发生?还是有人在该 UI 元素中单击屏幕上其他位置的结果。
    • 这种情况非常间歇性地发生。通常当我手动按下单选按钮或单击文本之外的某个位置时,它就会发生。
    • 我什至无法处理异常,因为当它发生时,它甚至在执行 RelayCommand 的方法之前就在 RelayCommand 类中中断。
    • 当您将 FlashImageForSelectedRow 方法更改为接受 Object 类型的属性,例如:private void FlashImageForSelectedRow(object myobj){} 而不是 InnerGridItems 然后按下单选按钮时,会发生异常吗?我测试了它,效果很好。如果仍然出现异常,能否提供一些关于您的 Command 实现的 sn-p 代码?
    猜你喜欢
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 1970-01-01
    • 2021-12-06
    相关资源
    最近更新 更多