【问题标题】:Unable to reselect single item in listview无法重新选择列表视图中的单个项目
【发布时间】:2016-05-03 21:08:42
【问题描述】:

我在一个 MVVM/PRISM 应用程序的 WPF 中有一个列表视图,它可能包含一对多的元素。当列表视图仅包含 1 个元素并且我选择它时,即使我将 SelectedIndedx 值设置为 -1,我也无法随后重新选择它。更糟糕的是,如果我让应用程序使用不同的单个元素更新列表视图,我也无法选择该元素。当它是列表视图中的唯一项目时,我可以实现对项目的选择的唯一方法是让应用程序显示多个项目并选择第一个以外的其他项目。然后,当我让应用程序显示一个包含单个项目的列表视图时,我可以再次选择它 - 但只能选择一次。

在我无法在列表视图中选择单个项目的情况下,服务例程永远不会触发。

我尝试使用“Listview.Container.Style”和 IsSelected 属性来实现我在此处找到的 XAML 建议,但这不起作用。

我的列表视图相当简单:

    <ListView Name="lstEditInstance"
          Grid.Row="5"
          ItemsSource="{Binding Path=InstanceList,Mode=TwoWay}"
          Width="488"
          FontFamily="Arial" FontSize="11"
          HorizontalAlignment="Left" VerticalAlignment="Stretch"    
          Margin="10,96,0,28"
          SelectedIndex="{Binding Path=InstanceSelectedIndex}">
    </ListView>

服务程序是:

    private void OnInstanceSelectedIndexChanged()
    {
      // Handle case where user hits Enter without making a selection:

      if (_instanceIndex == -1) return;

      // Get the instance record for the row the user clicked on as a
      // ResourceInstance class named "InstanceRecord".  

      InstanceRecord = _instanceList[_instanceIndex];

      _instanceNumber     = InstanceRecord.Instance;
      FormInstName        = InstanceRecord.InstName;
      FormInstEnabled     = InstanceRecord.Enabled;
      FormInstState       = InstanceRecord.InitialState;
      FormInstIPAddress   = InstanceRecord.IPAddress;
      FormInstPort        = InstanceRecord.Port.ToString();
      FormInstSelectedURL = InstanceRecord.UrlHandler;

    } // End of "OnResourceSelectedIndexChanged" method.

“InstanceList”是一个可观察的集合。

我会很感激一些建议。提前感谢您的帮助。

【问题讨论】:

    标签: c# wpf listview mvvm


    【解决方案1】:

    在 MVVM 场景中,我将使用包含所选项目的 ViewModel:

    class MyViewModel {
    
    private IList<Item> instanceList= new List<Item>();
    
    public IList<Item> List
    {
        get {return list; }
        set {
            list = value;
            RaisePropertyChanged(() => List);
        }
    }
    
    private Item selectedItem;
    
    public Item SelectedItem {
        get {return selectedItem;}
        set {
            selectedItem = value;
            RaisePropertyChanged(() => SelectedItem);
        }
    }}
    

    还有 XAML:

    <ListView Name="lstEditInstance"
      Grid.Row="5"
      ItemsSource="{Binding Path=InstanceList}"
      Width="488"
      FontFamily="Arial" FontSize="11"
      HorizontalAlignment="Left" VerticalAlignment="Stretch"    
      Margin="10,96,0,28"
      SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}}">
    

    请注意,除非您必须修改列表项,否则不需要 observableCollection,就像绑定应该是列表的默认值一样。 SelectedItem / SelectedIndex 应该是 TwoWay 或 Onewaytosource,后者如果您认为不需要以编程方式更改 selectedItem 应该从 ViewModel 调用服务例程

    编辑:

    你的服务例程代码应该放在那里:

    set {
        selectedItem = value;
        // your code
        RaisePropertyChanged(() => SelectedItem);
    }
    

    另一种有效的方法是在 XAML 上使用 Blend,通过在 ViewModel 下对更改的索引和进程调用命令。

    为此,首先在您的项目中添加对 System.Windows.Interactivity 的引用,然后在 XAML 中添加 xmlns:interactivity="http://schemas.microsoft.com/expression/2010/interactivity

    然后修改 ListView 如下:

    <ListView Name="lstEditInstance"
    Grid.Row="5"
    ItemsSource="{Binding Path=InstanceList}"
    Width="488"
    FontFamily="Arial" FontSize="11"
    HorizontalAlignment="Left" VerticalAlignment="Stretch"    
    Margin="10,96,0,28"
    SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}}">
    <interactivity:Interaction.Triggers>
    <interactivity:EventTrigger EventName="SelectionChanged">
      <interactivity:InvokeCommandAction Command="{Binding YourCommand}"
                             CommandParameter="{Binding YourCommandParameter}" />
    </interactivity:EventTrigger>
    </interactivity:Interaction.Triggers>
    

    【讨论】:

    • 致用户 3042207:服务例程在视图模型中,所选索引是一个属性。我很抱歉没有说清楚。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多