WPF中继承ItemsControl子类控件数据模板获取选中属性

需求场景

列表类控件,如 ListBox、ListView、DataGrid等。显示的行数据中,部分内容依靠选中时触发控制,例如选中行时行记录复选,部分列内容控制显隐。

案例源码以ListView 为例。

Xaml 部分

xaml 复制代码
<ListView ItemsSource="{Binding MyPropertys}" IsManipulationEnabled="False">
    <ListView.View>
        <GridView>
            <!--该列用于自定义行逻辑-->
            <GridViewColumn Header="操作列" >
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <!--该列用于自定义行逻辑-->
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="内容列" DisplayMemberBinding="{Binding MyProperty}"/>
            <GridViewColumn Header="内容列" DisplayMemberBinding="{Binding MyProperty1}"/>
            <GridViewColumn Header="内容列" DisplayMemberBinding="{Binding MyProperty2}"/>
            <GridViewColumn Header="内容列" DisplayMemberBinding="{Binding MyProperty3}"/>
        </GridView>
    </ListView.View>
</ListView>

ViewModel部分

CaseItemViewModel作为数据项

cs 复制代码
public class CaseItemViewModel
{
    public string MyProperty { get; set; }
    public string MyProperty1 { get; set; }
    public string MyProperty2 { get; set; }
    public string MyProperty3 { get; set; }
}

MainWindowViewModel作为上层ViewModel

cs 复制代码
public class MainWindowViewModel
{
    public List<CaseItemViewModel> MyPropertys { get; set; }

    public MainWindowViewModel()
    {
        MyPropertys = new List<CaseItemViewModel>
        {
            new CaseItemViewModel { MyProperty = "1", MyProperty1 = "1", MyProperty2 = "1", MyProperty3 = "1" },
            new CaseItemViewModel { MyProperty = "2", MyProperty1 = "2", MyProperty2 = "2", MyProperty3 = "2" },
            new CaseItemViewModel { MyProperty = "3", MyProperty1 = "3", MyProperty2 = "3", MyProperty3 = "3" },
            new CaseItemViewModel { MyProperty = "4", MyProperty1 = "4", MyProperty2 = "4", MyProperty3 = "4" },
            new CaseItemViewModel { MyProperty = "5", MyProperty1 = "5", MyProperty2 = "5", MyProperty3 = "5" }
        };
    }
}

设置MainWindowViewModel 到上层DataContext

cs 复制代码
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        // 设置上下文
        DataContext = new MainWindowViewModel();
    }
}

分析思路

ItemsControl 的子类控件,对应数据项多为xxxItem,该控件继承关系如下:

继承

Object\]--\>\[DispatcherObject\]--\>\[DependencyObject\]--\>\[Visual\]--\>\[UIElement\]--\>\[FrameworkElement\]--\>\[Control\]--\>\[ContentControl\]--\>\[ListBoxItem

派生

--->ComboBoxItem

--->ListViewItem

排查

通过Vs2022自带工具,查看对应的选中行页面对象。

选中行,开启三项。

鼠标悬浮,确认选择的是该元素节点。

点击转到实时可视化树,定位元素。弹出实时可视化树窗口。

可以看到已经选中节点,单击右键【显示属性】。

显示出对应的选中项实际UI元素当前属性。

其中属性关联项是ListBoxItem对应为IsSelected。是否可以考虑直接通过在数据模板中获取到UI 元素xxxItem的IsSelected 较少ViewModel 中添加额外属性。

cs 复制代码
public class ListViewItem : ListBoxItem
{
	
}

public class ListBoxItem : ContentControl
{
	public bool IsSelected { get; set; }
}

解决办法

方式一

如果是使用的MvvM架构设计,可以为控件的子项ViewModel 添加 IsSelected属性,从数据的维度去控制数据模板内的具体操作,此处不展开细说,主要以方式二为主。

cs 复制代码
public class CaseItemViewModel
{
	// 省略重复项
    public bool IsSelected { get; set; }
}

方式二(推荐)

纯UI层级处理,通过Binding 机制中提供的FindAncestor 方式,直接获取上级 Item 控件项属性。好处是ViewModel中,不需要再为了页面交互添加额外属性。

xaml 复制代码
<ListView ItemsSource="{Binding MyPropertys}" IsManipulationEnabled="False">
    <ListView.View>
        <GridView>
            <!--该列获取ListViewItem中的IsSelected属性-->
            <GridViewColumn Header="操作列" >
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <!--使用Binding机制中的FindAncestor,查找到ListViewItem的IsSelected属性-->
                        <CheckBox Content="操作项" 
              IsChecked="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}" 
              Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}"></CheckBox>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
             <!--省略重复内容-->
        </GridView>
    </ListView.View>
</ListView>
运行效果

非选中效果。

选中行效果。

相关推荐
Helix2506 小时前
Ansible混合环境自动化:Windows与Linux统一配置管理实战
windows·自动化·ansible·playbook·配置管理·winrm·混合环境
Java开发追求者7 小时前
windows快速安装docker
windows·docker·安装·1024程序员节
Helix25011 小时前
Windows ETW与KQL实战:终端性能诊断与遥测数据分析指南
windows·性能诊断·kql·etw·azure monitor·遥测数据·tracert
陈葛杰12 小时前
Adobe Premiere Pro2025安装教程
windows·adobe·开源软件·1024程序员节
承渊政道13 小时前
iOS远程控制电脑用什么好?iPhoneiPad远程控制Windows电脑最佳方案2026横评
windows·ios·远程控制·1024程序员节·iphone ipad
易点云徐源13 小时前
PDF 默认打开方式刚修好,过一分钟又变成“未知应用”?使用 ProcMon 成功抓出后台程序
windows·pdf
我是大猴子14 小时前
py how claude work项目分析
运维·服务器·windows·1024程序员节
paul_chen211 天前
解决Windows “此电脑”出现两个“图片”文件夹的问题
windows
SoulRoar.1 天前
在 Windows 上面部署 StartLux
windows·大模型·startlux
爱吃提升1 天前
DirectX修复工具安装配置教程-运行权限检测修复与运行库更新参数速查
windows