【问题标题】:Ability to get list of ListView items from checked items in WPF/C#?能够从 WPF/C# 中的选中项目中获取 ListView 项目列表吗?
【发布时间】:2017-11-18 17:28:00
【问题描述】:

我有一个包含两列的列表视图。第一列是复选框,第二列是服务器值。我想在单击按钮后获得该行中具有相应复选框的所有服务器名称的列表。这怎么可能?下面我能够从我的服务器模型中成功绑定数据并在第一列中放置一个复选框,但我被卡住了。

我正在尝试遵循 MVVM 模式,因此我有一个视图模型类,理想情况下我希望处理此逻辑,然后在检查的服务器名称存储在某个集合中之后将其传递。

XAML 代码

<ListView ItemsSource="{Binding Servers}" Margin="8,30,10,68">
    <ListView.View>
        <GridView>
            <GridViewColumn Width="90" Header="Select For Sync">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <CheckBox Tag="{Binding ID}" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListViewItem}}, Path=IsSelected}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Width="280" Header="Pad Name"  
                            DisplayMemberBinding="{Binding NodeName}" />
        </GridView>
    </ListView.View>
</ListView>

【问题讨论】:

  • “但我卡住了”,到底是什么问题?第二列没有显示任何内容吗?它只添加一行吗?如果Servers 中的每个数据都有一个布尔值,您的代码实际上可以被简化,以存储复选框是否被选中,我之前已经这样做过,如果需要可以提供一些示例代码。
  • @KeyurPATEL 我想将选中的复选框变成一个字符串集合,其中集合中的每个项目都是服务器列中的关联字符串名称。数据显示在第二列中,但我想根据第一列中检查的内容获取该数据
  • 我之前做过非常相似的事情,我会尝试调整我的部分代码以满足您的要求作为答案。

标签: c# wpf visual-studio data-binding


【解决方案1】:

我将简要描述我用于类似事情的方法。

首先,对于自定义类,它应该如下所示:

public class Server
{
    public int ID { get; set; }
    public bool isChecked { get; set; }     //or IsSelected maybe? whichever name you want  
    public string NodeName { get; set; }
}

对于你的 XAML,你可以使用这个:

<GridView>
    <GridViewColumn Width="90" Header="Select For Sync">
        <GridViewColumn.CellTemplate>
            <DataTemplate>
                <CheckBox Tag="{Binding ID}" IsChecked="{Binding isChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
            </DataTemplate>
        </GridViewColumn.CellTemplate>
    </GridViewColumn>
    <GridViewColumn Width="280" Header="Pad Name" DisplayMemberBinding="{Binding NodeName}" />
</GridView>

用于绑定到 ListView (Servers) 的集合/列表应该是上面的数据类型 Server。每当您需要访问选中的框和相应的行时,它都很简单:

List<Server> checkedRows = Servers.Where(s => s.isChecked).ToList(); //there, you now have a list of checked rows

或者如果你想要名字

List<string> nodeNames = Servers.Where(s => s.isChecked).Select(s => s.NodeName).ToList();

【讨论】:

  • 由于某种原因,此解决方案不起作用。我绑定了一个命令来打印checkedrows,函数被调用但列表是空的,不管我检查什么。
  • isChecked 的实际属性没有在服务器对象中得到变化
  • 你绑定的 ItemsSource,我可以看看实现吗(如果你使用的是 List&lt;Server&gt; Servers 或其他东西?)。基本上尝试使用ObservableCollection&lt;T&gt; ObservableCollection<T> Class 而不是列表。
【解决方案2】:

您应该将IsChecked 属性绑定到Server 类型的布尔属性,即T in你的IEnumerable&lt;T&gt;Servers源集合:

<ListView ItemsSource="{Binding Servers}" Margin="8,30,10,68">
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.View>
        <GridView>
            <GridViewColumn Width="90" Header="Select For Sync">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <CheckBox Tag="{Binding ID}" IsChecked="{Binding IsSelected}"></CheckBox>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Width="280" Header="Pad Name"  DisplayMemberBinding="{Binding NodeName}" />
        </GridView>
    </ListView.View>
</ListView>

然后您可以简单地遍历视图模型类中 Servers 集合中的记录并检查属性以确定当前选择了哪些项目:

var selectedItems = Servers.Where(x => x.IsSelected).ToList();
foreach(var selectedItem in selectedItems)
   ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 2018-02-15
    • 2015-10-20
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多