【问题标题】:Selecting all items in listview from ViewModel从 ViewModel 中选择列表视图中的所有项目
【发布时间】:2012-11-27 18:24:43
【问题描述】:

我的 WPF 窗口上有一个 ListView,并且我有一个按钮可以全选。首先,如何让按钮选择列表视图中的所有项目。

其次,我需要我的 ViewModel 来检查所有选定的项目。如何在我的 ViewModel 中获取这些信息?

我已经读过您可以使用 IsSelected 属性执行此操作,但有一个错误,即本地属性会覆盖绑定属性,因此如果之前已经选择了它,那么它似乎不会再次被选择 - 或类似的东西.看起来很复杂。 The blog that looks into this problem

然后我读了这个博客Data binding to selected items ,看起来也很复杂。

我想知道它是否必须如此复杂,并且这些示例是唯一的前进方向。

XAML:

        <ListView Name="sources_ListView" Grid.RowSpan="1" ItemsSource="{Binding Path=Sources}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="290" Header="Name">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Path=OriginalPath}" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Width="80" Header="Type">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Path=Type}" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>

<Button Grid.Row="0" Grid.Column="0" Content="Select All" Name="selectAllSources_Button" Margin="3" />
<Button Grid.Row="0" Grid.Column="1" Content="Deselect All" Name="deselectAllSources_Button" Margin="3" />
<Button Grid.Row="0" Grid.Column="3" Content="Remove Selected" Name="removeSelected_Button" Margin="3" Width="100" HorizontalAlignment="Right" />

【问题讨论】:

    标签: c# wpf mvvm visual-studio-2012


    【解决方案1】:

    在你的按钮上附加一个处理程序 -

    <Button Click="Button_Click"/>
    

    在您的 ListView 实例上调用 SelectAll 方法 -

    private void Button_Click(object sender, RoutedEventArgs e)
    {
       sources_ListView.SelectAll();
    }
    

    其次,如果在 View 上选择了所有项目,在这种情况下,ItemsSource 将始终等于SelectedItems。因此,在您的情况下,只需遍历 ItemsSource 即 Sources

    【讨论】:

    • 为什么不MVVM?我们可以在后面的代码中处理视图特定的事情,但与业务相关的逻辑应该始终存在于 ViewModel 中。不是吗?
    • 一个 MVVM 纯粹主义者会告诉你视图后面应该没有代码(除了构造函数)
    • 来自MSDN - Code-behind may contain UI logic code that implements visual behavior. You should not put any logic code in the view that you need to unit test.
    • @RV1987 我同意视图特定的代码可能存在于代码后面。但是我有一个问题:您如何处理 ViewModel 需要操纵选择的情况?我的意思是,根据 ViewModel 中定义的一些逻辑来选择或取消选择项目?
    • @HighCore - 是的,我也赞成 MVVM 模式,但这个答案仅参考 OP 的问题。他想在选择 ItemsSource 始终等于 selectedItems 的所有项目后遍历所有选定项目。可能还有其他方法可以解决这个问题,但我只建议简单的方法(不违反 MVVM)
    【解决方案2】:

    我创建了一种行为,允许控件中的属性绑定到项目集合的属性,其方式如下:

    • 如果您更改控件中的属性,所有项目都会更新。
    • 如果更改项目中的属性,如果所有项目都具有相同的属性,则控件将反映它。如果没有,控件的属性将被赋予一个后备值(如 null)。

    您可以使用它来将 CheckBox.IsChecked 绑定到该类型元素集合中的 IsSelected 类型属性。 我向一个想要做与您想要的类似的事情但使用 DataGrid 的人建议它。你可以看看here

    【讨论】:

      【解决方案3】:

      我很久以前创建了一个附加行为来处理这个问题。它允许您将 SelectedItems 列表绑定到 View Model 上的可观察集合并处理来回穿梭更改。

      使用附加行为是将功能扩展到现有控件(而不是子类化控件)的首选方法,否则将需要大量视图逻辑。

      我不会说您应该始终使用这种方法而不是在视图中放置逻辑。但这是一种捕获行为以便于重复使用的简单方法。

      【讨论】:

        【解决方案4】:

        @RV1987 感谢您的回答,这肯定是其中很大一部分。但是对于其余部分,我发现这个博客详细说明了如何使用源代码进行操作。绝对值得一读。

        Bad Entropy Blog

        谢谢

        【讨论】:

          猜你喜欢
          • 2012-04-04
          • 2014-09-01
          • 1970-01-01
          • 2016-10-26
          • 1970-01-01
          • 1970-01-01
          • 2011-09-15
          • 1970-01-01
          • 2016-01-20
          相关资源
          最近更新 更多