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 元素xxxItemIsSelected 较少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>
运行效果

非选中效果。

选中行效果。

相关推荐
熊明才13 小时前
WSL2 网络突然瘫痪(Network is unreachable / 没有 eth0)最短修复指南(2026年9月20日亲测可用)
linux·windows·wsl2
xbzb17 小时前
Windows 启动故障修复知识整理:蓝屏 / 无限重启 / 盘符 X / 无 PE 盘
windows
我命由我1234518 小时前
Mac 操作系统 - 一些使用记录
运维·windows·学习·系统安全·运维开发·mac·学习方法
kakakahahahaha1 天前
Windows Steam 游戏存档在哪里?定位和恢复排查流程
windows·其他·电脑·笔记本电脑·内容运营·软件需求
Xy-unu1 天前
Windows 开启外接显示器 HDR 后外接显示器无信号、无法扩展模式故障记录
windows
troy1281 天前
Codex 安全盲区:代码漏洞生成实测
windows·python·ci/cd·pycharm·django·github·fastapi
其实防守也摸鱼1 天前
常见安全架构中 Shiro 的认证确认机制解析
运维·服务器·数据库·windows·github
五_谷_丰_登2 天前
windows批处理脚本(bat)问题解决方案大全——持续更新
windows·bat
YCOSA20252 天前
迎双节 雨晨 Windows 11 IoT 企业版 LTSC 26H1 轻装 28000.2956
windows·物联网
csdn_aspnet2 天前
Windows 如何隐藏 IIS Web 服务响应头中的 IIS Server 版本信息
windows·iis·url rewrite