将table中行的赋值到其他模块去维护不显示,this.$forceUpdate()无效,刷新key 放到完整模块里不可行

通义AI:

在 Vue 中,如果你希望强制重新渲染组件,可以使用以下几种方法:

  1. 使用 key 属性: 通过改变组件的 key 属性,Vue 会认为这是一个新的组件实例,从而重新渲染组件。

    vue

    <template> <z-modal v-model="modelIsOpen" :key="componentKey" :title="title" fixed height="550" width="1200" :mask-closable="false" @on-cancel="closeEdit"> <!-- 其他内容 --> </z-modal> </template> <script> export default { data() { return { componentKey: 0, // 其他数据 } }, methods: { forceRerender() { this.componentKey += 1; } } } </script>

  2. 使用 this.$forceUpdate(): Vue 提供了一个 $forceUpdate 方法,可以强制组件重新渲染。虽然这种方法不推荐频繁使用,但在某些情况下可以解决问题。

    javascript

    methods: { forceRerender() { this.$forceUpdate(); } }

  3. 使用 v-if 指令: 通过控制组件的显示和隐藏,可以达到重新渲染的效果。

    vue

    <template> <z-modal v-if="isRendered" v-model="modelIsOpen" :title="title" fixed height="550" width="1200" :mask-closable="false" @on-cancel="closeEdit"> <!-- 其他内容 --> </z-modal> </template> <script> export default { data() { return { isRendered: true, // 其他数据 } }, methods: { forceRerender() { this.isRendered = false; this.$nextTick(() => { this.isRendered = true; }); } } } </script>

实践结果是

测试页面为弹出框

第一种方式,需要将 :key="componentKey" 放到指定模块里,而不能放到<template> <z-modal :key="componentKey"></z-modal></template> 最顶层模块上,在该标签上会整个页面都重新渲染,导致渲染出多个页面,

比如<template> <z-modal></z-modal></template> 下有某个模块

<template> <z-modal><z-form><z-list-panel :key="componentKey"></z-list-panel></z-form></z-modal></template>

第二种方式测试未生效。

第三种方式未测试。

<template> <el-dialog :title="dialogMode === 'create' ? '新建' : dialogMode === 'edit' ? '修改' : '查看'" :visible.sync="dialogVisible" :modal-append-to-body="true" append-to-body :close-on-click-modal="false" custom-class="fixed-height-dialog" width="60%" top="5vh"> <el-form label-width="80px" ref="formRef" :model="currentForm" style="height: 100%; display: flex; flex-direction: column;" :rules="rules"> <!-- 项目信息区域 --> <div class="formBorder"> <el-row :gutter="10"> <el-col :span="6"> <el-form-item size="mini" label="项目名称" prop="projectName"> <el-input v-model="currentForm.projectName" clearable style="width:100%" size="mini" :disabled="dialogMode === 'view'"></el-input> </el-form-item> </el-col> <el-col :span="6"> <el-form-item size="mini" label="项目编号" prop="projectCode"> <el-input v-model="currentForm.projectCode" clearable style="width:100%" size="mini" :disabled="dialogMode === 'view'"></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item size="mini" label="项目周期" prop="projectDate"> <el-date-picker v-model="projectDate" range-separator="→" start-placeholder="请选择开始日期" end-placeholder="请选择结束日期" type="daterange" size="mini" style="width: 100%;" unlink-panels :disabled="dialogMode === 'view'"> </el-date-picker> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="6"> <el-form-item label="负责人" size="mini" style="width: fit-content;"> <el-input v-model="currentForm.projectUser" clearable style="width:100%" size="mini" :disabled="dialogMode === 'view'"></el-input> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="24"> <el-form-item label="项目概述"> <el-input v-model="currentForm.remark" :rows="2" :disabled="dialogMode === 'view'"></el-input> </el-form-item> </el-col> </el-row> </div> <!-- 待检边坡区域 - 使用纯CSS控制高度 --> <div class="formBorder2"> <el-container style="height: 100%;"> <!-- 搜索区域 --> <el-header style="height: auto; flex-shrink: 0; padding-bottom: 10px;"> <el-row :gutter="10" type="flex" class="searchDialog"> <el-col :span="5"> <el-select v-model="filterForm.maintenanceCompanyName" placeholder="请选择管养单位" size="mini" clearable filterable @clear="resetSearch" :disabled="dialogMode === 'view'"> <el-option v-for="item in MaintenanceUnitoptions" :key="item.value" :label="item.label" :value="item.value"></el-option> </el-select> </el-col> <el-col :span="5"> <el-select v-model="filterForm.routeCode" placeholder="请选择路线编号" size="mini" clearable filterable @clear="resetSearch" :disabled="dialogMode === 'view'"> <el-option v-for="item in routeCodeOptions" :key="item.value" :label="item.label" :value="item.value"></el-option> </el-select> </el-col> <el-col :span="5"> <el-input v-model="filterForm.searchKey" placeholder="请输入边坡编号或名称" size="mini" clearable @keyup.enter.native="searchForm" @clear="resetSearch" :disabled="dialogMode === 'view'"> <i slot="suffix" class="el-input__icon el-icon-search"></i> </el-input> </el-col> <el-col :span="5"> <el-select v-model="filterForm.evaluateLevel" placeholder="请选择技术状态等级" size="mini" clearable @clear="resetSearch" :disabled="dialogMode === 'view'"> <el-option v-for="item in evaluateLeveloptions" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-col> <el-col :span="2" :offset="4"> <el-button type="primary" size="mini" style="width:100%" icon="el-icon-search" @click="searchForm" :loading="loading" :disabled="dialogMode === 'view'">搜索</el-button> </el-col> </el-row> </el-header> <!-- 边坡表格 - 移除动态高度绑定 --> <el-main style="overflow-y: auto;"> <el-table ref="scrollTable" v-loading="loading" style="width: 100%;" border :data="formTabledata" :header-row-style="{ height: '40px' }" :header-cell-style="{ padding: '0', height: '40px', lineHeight: '40px', textAlign: 'center', }" :cell-style="{ textAlign: 'center' }" @selection-change="handleSelectionChange" :row-key="getRowkey"> <!-- 选择列(查看模式禁用) --> <el-table-column type="selection" width="55" :selectable="isRowSelectable" :reserve-selection="true"> </el-table-column> <!-- 其他数据列 --> <el-table-column label="管养单位" prop="maintenanceCompanyName" width="290" show-overflow-tooltip></el-table-column> <el-table-column label="路线编号" prop="routeCode" width="100"></el-table-column> <el-table-column label="边坡编号" prop="sideSlopeCode" width="240" show-overflow-tooltip></el-table-column> <el-table-column label="边坡名称" prop="sideSlopeName" width="267" show-overflow-tooltip></el-table-column> <el-table-column label="技术状态等级" width="137"> <template slot-scope="scope"> {{ mapEvaluateLevel(scope.row.evaluateLevel) }} </template> </el-table-column> </el-table> </el-main> <!-- 分页区域 --> <el-footer style="flex-shrink: 0; padding-top: 10px;"> <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageParams.pageNo" :page-sizes="[10, 20, 50, 100]" :page-size="pageParams.pageSize" layout="total, sizes, prev, pager, next" :total="total"> </el-pagination> </el-footer> </el-container> </div> </el-form> <!-- 弹窗底部按钮 --> <div slot="footer" class="dialog-footer" v-if="dialogMode === 'create' || dialogMode === 'edit'"> <el-button @click="dialogVisible = false">取消</el-button> <el-button type="primary" @click="submitForm">提交</el-button> </div> </el-dialog> </template> <script> import { mapCfg } from "@/utils"; import { getPeriodicInspectionSideSlopePageList, addPeriodicInspection, modifyPeriodicInspection, getSelectedPeriodicInspectionSideSlopeList } from "../../api/testProject"; import { getMaintenanceCompanyList, getRouteList } from "../../api/basicInformation"; export default { name: "SideSlopeDialog", props: { visible: Boolean, // 控制弹窗显示 mode: String, // 模式:create/edit/view initialForm: Object, // 初始表单数据 }, data() { return { dialogVisible: this.visible, // 弹窗显示状态 dialogMode: this.mode, // 当前模式 currentForm: { ...this.initialForm }, // 当前表单数据 projectDate: [], // 项目日期范围 total: 0, // 总数据量 loading: false, // 加载状态 pageParams: { // 分页参数 pageNo: 1, pageSize: 10, }, filterForm: { // 搜索条件 maintenanceCompanyName: "", routeCode: "", searchKey: "", evaluateLevel: "", }, allSelection: new Map(), // 存储所有选择的边坡(使用Map提高性能) MaintenanceUnitoptions: [], // 管养单位选项 routeCodeOptions: [], // 路线编号选项 formTabledata: [], // 表格数据 evaluateLeveloptions: [], // 技术状态等级选项 rules: { // 表单验证规则 projectName: [ { required: true, message: "项目名称能为空", trigger: "blur" }, ], projectCode: [ { required: true, message: "项目编码能为空", trigger: "blur" }, ], }, }; }, watch: { // 监听模式变化 mode(val) { this.dialogMode = val; }, // 监听弹窗显示状态变化 visible(val) { this.dialogVisible = val; if (val) { // 打开对话框时 if (this.dialogMode !== 'create' && this.currentForm.id) { this.getSelectedSlopes(); } else { this.resetAllData(); // 新增:完全重置状态 } } else { // 关闭对话框时 - 关键修复:完全重置组件状态 this.resetAllData(); } }, // 同步弹窗显示状态到父组件 dialogVisible(val) { this.$emit("update:visible", val); }, // 监听初始表单数据变化 initialForm: { deep: true, handler(val) { this.currentForm = { ...val }; this.projectDate = val.projectStartDate && val.projectEndDate ? [val.projectStartDate, val.projectEndDate] : []; // 关键修改:表单数据更新后重新加载已选边坡 if (this.dialogVisible && this.dialogMode !== 'create' && val.id) { this.getSelectedSlopes(); } }, }, // 处理日期范围变化 projectDate: { deep: true, handler(value) { if (value && value.length === 2) { this.currentForm.projectStartDate = value[0]; this.currentForm.projectEndDate = value[1]; } }, }, }, async created() { // 初始化数据 this.getRouteList(); await this.getEvaluateLevel(); this.getMaintenanceCompanyList(); }, methods: { // 在methods中添加排序方法 sortSelectedToTop(data) { return [...data].sort((a, b) => { const aSelected = this.allSelection.has(a.sideSlopeUniqueCode); const bSelected = this.allSelection.has(b.sideSlopeUniqueCode); return bSelected - aSelected; // 选中的排在前面 }); }, getRowkey(row) { return row.id }, // 获取已选择的边坡(优化版) async getSelectedSlopes() { try { this.resetSelection(); const params = { periodicId: this.currentForm.id, pageNo: 1, pageSize: 1000 }; const res = await getSelectedPeriodicInspectionSideSlopeList(params); // 关键修改:将已选边坡数据赋值给表格 const selectedSlopes = res.entities || []; this.formTabledata = selectedSlopes; // 显示已选边坡 this.total = selectedSlopes.length; // 设置总条数 // 存储所有已选边坡 this.allSelection = new Map(); selectedSlopes.forEach(item => { this.allSelection.set(item.sideSlopeUniqueCode, item); }); // 设置表格选中状态 this.$nextTick(() => { this.setSelectedRows(); }); } catch (error) { console.error('获取已选边坡失败', error); this.$message.error('获取已选边坡数据失败'); this.formTabledata = []; this.total = 0; } }, // 设置选中行 setSelectedRows() { if (!this.$refs.scrollTable) return; // 添加防抖确保只执行一次 clearTimeout(this.selectionTimer); this.selectionTimer = setTimeout(() => { this.$refs.scrollTable.clearSelection(); // 检查表格行是否已渲染 const tableRows = this.$refs.scrollTable.$el.querySelectorAll('.el-table__row'); if (tableRows.length === 0) { this.setSelectedRows(); // 递归直到行渲染完成 return; } // 设置选中状态 const keys = new Set(this.allSelection.keys()); this.formTabledata.forEach(row => { if (keys.has(row.sideSlopeUniqueCode)) { this.$refs.scrollTable.toggleRowSelection(row, true); } }); }, 150); // 适当延长等待时间 }, // 判断行是否可选(查看模式禁用选择) isRowSelectable(row, index) { return this.dialogMode !== "view"; }, // 获取管养单位列表 async getMaintenanceCompanyList() { const res = await getMaintenanceCompanyList(); this.MaintenanceUnitoptions = res.map((item) => ({ value: item, label: item, })); }, // 获取路线列表 async getRouteList() { const res = await getRouteList(); this.routeCodeOptions = res.map((item) => ({ value: item.id, label: item.routeCode, })); }, // 搜索方法 searchForm() { this.pageParams.pageNo = 1; this.LoadListData(); }, // 重置搜索条件 resetSearch() { this.filterForm = { maintenanceCompanyName: "", routeCode: "", searchKey: "", evaluateLevel: "", }; this.pageParams.pageNo = 1; this.LoadListData(); }, // 新增:完全重置组件状态 resetAllData() { this.resetSelection(); this.formTabledata = []; // 清空表格数据 this.total = 0; // 重置总条数 this.pageParams = { // 重置分页 pageNo: 1, pageSize: 10 }; // 重置搜索条件(可选) this.filterForm = { maintenanceCompanyName: "", routeCode: "", searchKey: "", evaluateLevel: "" }; }, // 修改原有方法 resetSelection() { this.allSelection = new Map(); if (this.$refs.scrollTable) { this.$refs.scrollTable.clearSelection(); } }, // 处理选择变化 handleSelectionChange(val) { // 查看模式允许修改选择 if (this.dialogMode === 'view') return; // 创建当前页行ID的Set const currentPageIds = new Set( this.formTabledata.map(item => item.sideSlopeUniqueCode) ); // 移除当前页在新选择中的行 for (const key of this.allSelection.keys()) { if (currentPageIds.has(key)) { this.allSelection.delete(key); } } // 添加新选择的行 val.forEach(row => { this.allSelection.set(row.sideSlopeUniqueCode, row); }); }, // 映射技术状态等级 mapEvaluateLevel(level) { const option = this.evaluateLeveloptions.find( (item) => item.value === level ); return option ? option.label : ''; }, // 加载表格数据 async LoadListData() { this.loading = true; const params = { orgId: this.filterForm.maintenanceCompanyName, routeId: this.filterForm.routeCode, searchKey: this.filterForm.searchKey, evaluateLevel: this.filterForm.evaluateLevel, pageSize: this.pageParams.pageSize, pageNo: this.pageParams.pageNo, }; try { const res = await getPeriodicInspectionSideSlopePageList(params); // 关键修改:保留原数据的选中状态 const newData = res.entities || []; this.formTabledata = this.sortSelectedToTop(newData); this.total = res.entityCount || 0; } finally { this.loading = false; } // 确保在数据渲染后设置选中状态 this.$nextTick(() => { this.setSelectedRows(); }); }, // 保留选中状态的映射方法 preserveSelectionState(newData) { return newData.map(item => { // 检查此条目是否在全局选中Map中 const isSelected = this.allSelection.has(item.sideSlopeUniqueCode); // 返回新对象,携带选中状态 return { ...item, _isSelected: isSelected }; }); }, // 分页大小变化 handleSizeChange(val) { this.pageParams.pageSize = val; this.pageParams.pageNo = 1; this.LoadListData(); }, // 当前页码变化 handleCurrentChange(val) { this.pageParams.pageNo = val; this.LoadListData(); }, // 获取技术状态等级选项 async getEvaluateLevel() { const levelList = await mapCfg("Inspection.Regular.RegularEvaluateLevel")(); this.evaluateLeveloptions = levelList.map((item) => ({ value: item.key, label: item.value, })); }, // 提交表单 async submitForm() { this.$refs.formRef.validate(async (valid) => { if (valid) { // 验证是否选择了边坡 if (this.allSelection.size === 0) { this.$message.warning("请至少选择一个边坡"); return; } // 构造提交参数 const params = { ...this.currentForm, sideSlopeDetailList: Array.from(this.allSelection.values()).map((item) => ({ sideSlopeUniqueCode: item.sideSlopeUniqueCode, evaluateLevel: item.evaluateLevel, evaluateDate: item.evaluateDate ? item.evaluateDate : undefined, })), }; // 根据模式选择操作 const action = this.dialogMode === "create" ? addPeriodicInspection : modifyPeriodicInspection; // 执行操作 try { const success = await action(params); if (success) { this.$message.success( this.dialogMode === "create" ? "新建成功" : "修改成功" ); this.$refs.scrollTable.clearSelection(); this.$emit("success"); this.dialogVisible = false; } else { this.$message.error("操作失败"); } } catch (error) { this.$message.error(error.message || "操作失败"); } } }); } }, }; </script> <style lang="scss" scoped> :deep(.fixed-height-dialog) { .el-dialog { display: flex; flex-direction: column; max-height: 80vh !important; height: 80vh !important; .el-dialog__body { flex: 1; overflow: hidden; padding: 15px 20px; display: flex; flex-direction: column; } } } // 项目信息区域样式 .formBorder { position: relative; border: thin dotted black; padding: 10px; flex-shrink: 0; &::before { content: "项目信息"; position: absolute; top: -10px; left: 40px; background-color: #fff; padding: 0 10px; font-size: 14px; color: #606266; } } .formBorder2 { margin-top: 15px; position: relative; border: thin dotted black; padding: 10px; flex-shrink: 0; &::before { content: "待检边坡"; position: absolute; top: -10px; left: 40px; background-color: #fff; padding: 0 10px; font-size: 14px; color: #606266; } .el-container { height: 100%; display: flex; flex-direction: column; .el-header { flex-shrink: 0; /* 固定高度 */ } .el-main { flex: 1; /* 占据剩余空间 */ overflow-y: auto; /* 自动滚动 */ padding: 0; } .el-footer { flex-shrink: 0; /* 固定高度 */ } } } // 弹窗底部按钮区域 .dialog-footer { padding: 10px 20px; border-top: 1px solid #ebeef5; text-align: center; } // 搜索区域样式 .searchDialog { margin-top: 5px; } // 空数据样式 :deep(.el-table__empty-block) { min-height: 200px; display: flex; justify-content: center; align-items: center; } // 分页样式 :deep(.el-pagination) { padding: 5px 0; } </style> 为什么编辑界面搜索排序之后已经勾选的选项就取消勾选了
08-21
using DBWAT; using EBCore; using EBEmpower; using GuiDB; using Microsoft.Office.Core; using Microsoft.Win32; using SharpDX.Direct2D1; using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Security.RightsManagement; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Forms; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Markup; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Xceed.Wpf.Toolkit; using Xceed.Wpf.Toolkit.Panels; using Xceed.Wpf.Toolkit.Primitives; using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; using static System.Windows.Forms.AxHost; using static System.Windows.Forms.ImageList; using static System.Windows.Forms.VisualStyles.VisualStyleElement; using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock; using Bitmap = System.Drawing.Bitmap; using Brushes = System.Windows.Media.Brushes; using Clipboard = System.Windows.Clipboard; using Color = System.Drawing.Color; using ComboBox = System.Windows.Forms.ComboBox; using ContextMenu = System.Windows.Controls.ContextMenu; using DataGridCell = System.Windows.Controls.DataGridCell; using Image = System.Drawing.Image; using MenuItem = System.Windows.Controls.MenuItem; using MessageBox = System.Windows.MessageBox; using Point = System.Drawing.Point; using Size = System.Drawing.Size; using TextBox = System.Windows.Controls.TextBox; using Window = System.Windows.Window; namespace WatDe_EB { ///用户界面View,用户可见部分,接收展示数据,用于用户输入。 /// </summary> public partial class ProofreadListView : Window { /// <summary> /// 校审内容ViewModel /// </summary> public static ProofreadListViewModel pfviewModel = new ProofreadListViewModel(); /// <summary> /// 校审内容Model集合(接受功能的代码合集) /// </summary> public static List<ProofreadListModel> pfModels = new List<ProofreadListModel>(); /// <summary> /// 当前鼠标点击数据项在数据项集合中的索引 /// 用于索引当前数据项对应的云线标记(传递数据至功能代码) /// </summary> public static int CurrentIndex; /// <summary> /// 选定云线标记集合(接受功能代码数据) /// </summary> public static List<CloudLinePZ_P> PZ_P = new List<CloudLinePZ_P>(); /// <summary> /// 申明校审列表窗口 /// </summary> public static ProofreadListView wpf1 = null; public ProofreadListView() { InitializeComponent(); this.Owner = System.Windows.Application.Current.MainWindow; pfDataGrid.DataContext = pfviewModel; pfviewModel.DataItems.Clear(); pfviewModel.AddRange(pfModels); CurrentIndex = -1; this.Closed += MainWinClosed; // 初始化 RichTextBox 上下文菜单 InitializeRichTextBoxContextMenu(); } /// <summary> /// 窗口关闭时执行 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MainWinClosed(object sender, EventArgs e) { PZ_P.Clear();//功能性的内容进行清除 pfviewModel.DataItems.Clear(); pfModels.Clear(); EBDB.Instance.UIReDrawAll(); EBDB.Instance.UICloseLastCMD(); } /// <summary> /// 初始化上下文菜单 /// </summary> private void InitializeRichTextBoxContextMenu() { ContextMenu menu = new ContextMenu(); MenuItem pasteItem = new MenuItem { Header = "粘贴图片", Command = ApplicationCommands.Paste }; MenuItem clearItem = new MenuItem { Header = "清空图片" }; clearItem.Click += (s, e) => rtbImages3.Document.Blocks.Clear(); menu.Items.Add(pasteItem); menu.Items.Add(clearItem); rtbImages3.ContextMenu = menu; } //各类点击事件 #region /// <summary> /// 单元格点击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void DataGridCell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var cell = sender as DataGridCell;//申明一个cell单元格用来储存DataGridCell现有单元格中的数据 if (cell != null) { DataGridRow row = FindVisualParent<DataGridRow>(cell);//获取该单元格所在的行 if (row != null) { row.IsSelected = true;//选中当前行 } } //定位指定云线位置 if (cell != null && cell?.Column.Header.ToString() == "意见内容") { EBDB.Instance.UICloseLastCMD(); //数据项在数据源集合的索引 CurrentIndex = GetRowIndex(cell); EBDB.Instance.CmdRun("WatDe_EB.PositionYunxianPZ"); RenewalNum(pfviewModel.DataItems); } //点击修改状态打开PZEdit if (cell != null && cell?.Column.Header.ToString() == "修改状态" || cell != null && cell?.Column.Header.ToString() == "问题性质") { EBDB.Instance.UICloseLastCMD(); //数据项在数据源集合的索引 CurrentIndex = GetRowIndex(cell); EBDB.Instance.CmdRun("WatDe_EB.OpenPZEdit"); RenewalNum(pfviewModel.DataItems); } //if (cell != null && cell?.Column.Header.ToString() == "序号") //{ // EBDB.Instance.UICloseLastCMD(); // //数据项在数据源集合的索引 // CurrentIndex = GetRowIndex(cell); // RenewalNum(pfviewModel.DataItems); //} } /// <summary> /// 辅助方法:查找父级控件(如 DataGridRow 或 DataGridCell) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="child"></param> /// <returns></returns> private T FindVisualParent<T>(DependencyObject child) where T : DependencyObject { while (child != null && !(child is T)) { child = VisualTreeHelper.GetParent(child); } return child as T; } /// <summary> /// 获取单元格的数据源集合中的索引 /// </summary> /// <param name="cell"></param> /// <returns></returns> private int GetRowIndex(DataGridCell cell) { var item = cell.DataContext;//获取行的绑定数据的对象 var collection = pfDataGrid.ItemsSource as IList; return collection?.IndexOf(item) ?? -1; } /// <summary> /// 更新数据项在界面的序号 /// </summary> /// <param name="DataItems"></param> public void RenewalNum(ObservableCollection<ProofreadListModel> DataItems) { for (int i = 0; i < pfviewModel.DataItems.Count; i++) { pfviewModel.DataItems[i].SerialNumber = i + 1; } } /// <summary> /// 数据导出按钮 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void DataExport_Btn_Click(object sender, RoutedEventArgs e) { EBDB.Instance.UICloseLastCMD(); EBDB.Instance.CmdRun(DrawProofTable); } /// <summary> /// 数据导出功能 /// </summary> public void DrawProofTable() { using (new Transaction("校审列表")) { if (EBDB.Instance.ActivView2D == null) { EBDB.Instance.UICmdLine("请在二维平面下使用该功能", null, null); return; } //窗口隐藏 EBDB.Instance.textBox.Dispatcher.Invoke(() => { this.Hide(); }); DbTable table = new DbTable(); //第一列序号 DbTableColumn column1 = new DbTableColumn(); for (int i = -1; i < pfviewModel.DataItems.Count; i++) { DbTableCell cell = null; if (i == -1) { cell = new DbTableCell("序号"); column1.Cells.Add(cell); continue; } cell = new DbTableCell((i + 1).ToString()); column1.Cells.Add(cell); } table.Columns.Add(column1); //第二列意见内容 DbTableColumn column2 = new DbTableColumn(); for (int i = -1; i < pfviewModel.DataItems.Count; i++) { DbTableCell cell = null; if (i == -1) { cell = new DbTableCell("意见内容"); column2.Cells.Add(cell); continue; } cell = new DbTableCell(pfviewModel.DataItems[i].OpinionContent.ToString()); column2.Cells.Add(cell); } table.Columns.Add(column2); //第三列批注时间 DbTableColumn column3 = new DbTableColumn(); for (int i = -1; i < pfviewModel.DataItems.Count; i++) { DbTableCell cell = null; if (i == -1) { cell = new DbTableCell("批注时间"); column3.Cells.Add(cell); continue; } cell = new DbTableCell(pfviewModel.DataItems[i].AnnotationTime.ToString()); column3.Cells.Add(cell); } table.Columns.Add(column3); //第四列修改状态 DbTableColumn column4 = new DbTableColumn(); for (int i = -1; i < pfviewModel.DataItems.Count; i++) { DbTableCell cell = null; if (i == -1) { cell = new DbTableCell("修改状态"); column4.Cells.Add(cell); continue; } cell = new DbTableCell(pfviewModel.DataItems[i].ModifyStatus.ToString()); column4.Cells.Add(cell); } table.Columns.Add(column4); //第五列批注人员 DbTableColumn column5 = new DbTableColumn(); for (int i = -1; i < pfviewModel.DataItems.Count; i++) { DbTableCell cell = null; if (i == -1) { cell = new DbTableCell("批注人员"); column5.Cells.Add(cell); continue; } cell = new DbTableCell(pfviewModel.DataItems[i].Annotator.ToString()); column5.Cells.Add(cell); } table.Columns.Add(column5); //第六列问题性质 DbTableColumn column6 = new DbTableColumn(); for (int i = -1; i < pfviewModel.DataItems.Count; i++) { DbTableCell cell = null; if (i == -1) { cell = new DbTableCell("批注人员"); column6.Cells.Add(cell); continue; } cell = new DbTableCell(pfviewModel.DataItems[i].ProblemNature.ToString()); column6.Cells.Add(cell); } table.Columns.Add(column6); DbPt pt = EBDB.Instance.UIPickPoint("请选择表格左上角插入点"); if (pt == null) { //打开窗口 EBDB.Instance.textBox.Dispatcher.Invoke(() => { this.Show(); }); } var gTable = new GuiDB.Table(pt, table, -1); gTable.ColumnWidth = 1000; gTable.RowHeight = 300; gTable.Activate(); EBDB.Instance.ActivView2D.GView.AddElement(gTable); EBDB.Instance.UIReDrawAll(); while (true) { DbPt tempPt = EBDB.Instance.UIPickPoint("请按ESC键退出"); if (tempPt == null) { break; } } //打开窗口 EBDB.Instance.textBox.Dispatcher.Invoke(() => { this.Show(); }); } } /// <summary> /// 全部标记已确认 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MarkAll_Btn_Click(object sender, RoutedEventArgs e) { for (int i = 0; i < pfviewModel.DataItems.Count; i++) { if (pfviewModel.DataItems[i].ModifyStatus == "待确认" || pfviewModel.DataItems[i].ModifyStatus == "待修改") { pfviewModel.DataItems[i].ModifyStatus = "已确认"; PZ_P[i].PZMS = pfviewModel.DataItems[i].ModifyStatus;//这对图元显示有关联 PZMS和pzMS区别同 //PZ_P[i].pzMS = PZ_P[i].PZMS; } } } /// <summary> /// 全标记待修改 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void CancelMarkAll_Btn_Click(object sender, RoutedEventArgs e) { for (int i = 0; i < pfviewModel.DataItems.Count; i++) { if (pfviewModel.DataItems[i].ModifyStatus == "已确认") { pfviewModel.DataItems[i].ModifyStatus = "待修改"; PZ_P[i].PZMS = pfviewModel.DataItems[i].ModifyStatus;//这对图元显示有关联 PZMS和pzMS区别同 //PZ_P[i].PZMS = PZ_P[i].pzMS; } } } /// <summary> /// 退出按钮 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Exit_Btn_Click(object sender, RoutedEventArgs e) { this.Close(); } #endregion //加载示意图事件 /// <summary> /// 修改前-加载图片 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void rtbImages3_GotFocus(object sender, RoutedEventArgs e) { // 获得焦点时添加提示文本 if (rtbImages3.Document.Blocks.Count == 1) { AddHintText(); } } // 添加类级变量标记提示段落 private Paragraph _hintParagraph; // 提取提示文本添加方法 private void AddHintText() { _hintParagraph = new Paragraph(new Run("请截图后使用Ctrl+V粘贴图片...")); rtbImages3.Document.Blocks.Add(_hintParagraph); } // 提取移除文本添加方法 private void RemoveHintText() { if (_hintParagraph != null && rtbImages3.Document.Blocks.Contains(_hintParagraph)) { rtbImages3.Document.Blocks.Remove(_hintParagraph); _hintParagraph = null; // 清除引用 } } private void rtbImages3_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) { // 直接响应Ctrl+V粘贴 if (e.Key == Key.V && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) { PasteImageToRichTextBox(); e.Handled = true; // 阻止事件继续传播 } } /// <summary> /// 粘贴截图并保存至富文本 /// </summary> private const double MaxImageWidth = 300; // 最大显示宽度 private const double MaxImageHeight = 150; // 最大显示高度 private void PasteImageToRichTextBox() { if (!Clipboard.ContainsImage()) { MessageBox.Show("剪贴板中没有图片"); return; } Dispatcher.Invoke(() => { try { // 清除提示文本 RemoveHintText(); // 图片保存路径 string ImageSavePath = "C:/ProgramData/EasyBIM/Proofread/"; // 确保目录存在 if (!Directory.Exists(ImageSavePath)) { Directory.CreateDirectory(ImageSavePath); } // 生成唯一文件名 string timestamp = DateTime.Now.ToString("yyyyMMddHHmmss"); string fileName = $"Image_{timestamp}.png"; string filePath = System.IO.Path.Combine(ImageSavePath, fileName); // 直接从剪贴板获取BitmapSource BitmapSource clipboardImage = Clipboard.GetImage(); if (clipboardImage == null) return; // 直接使用BitmapFrame创建BitmapImage BitmapImage bitmapImage; using (MemoryStream stream = new MemoryStream()) { // 使用BmpBitmapEncoder替代PngBitmapEncoder解决兼容性问题 BmpBitmapEncoder encoder = new BmpBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(clipboardImage)); encoder.Save(stream); stream.Position = 0; bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.StreamSource = stream; bitmapImage.EndInit(); } // 计算缩放比例 double scaleRatio = Math.Min( MaxImageWidth / bitmapImage.PixelWidth, MaxImageHeight / bitmapImage.PixelHeight ); scaleRatio = Math.Min(scaleRatio, 1.0); // 确保放大图片 // 创建图像控件 var imageControl = new System.Windows.Controls.Image { Source = bitmapImage, Width = bitmapImage.PixelWidth * scaleRatio, Height = bitmapImage.PixelHeight * scaleRatio, Stretch = Stretch.Uniform, Margin = new Thickness(0, 5, 0, 5) }; // 创建容器 Border imageBorder = new Border { Child = imageControl, BorderBrush = Brushes.LightGray, BorderThickness = new Thickness(1), CornerRadius = new CornerRadius(4), Background = Brushes.White, Padding = new Thickness(2) }; // 创建InlineUIContainer InlineUIContainer container = new InlineUIContainer(imageBorder) { BaselineAlignment = BaselineAlignment.Center // 确保垂直居中 }; // 获取当前段落 Paragraph currentParagraph = rtbImages3.CaretPosition.Paragraph ?? new Paragraph(); // 如果是空文档则添加新段落 if (rtbImages3.Document.Blocks.Count == 0) { rtbImages3.Document.Blocks.Add(currentParagraph); } // 添加图片到段落 currentParagraph.Inlines.Add(container); // 设置新光标位置 rtbImages3.CaretPosition = container.ElementEnd; //将路径关联到当前选中的行后保存图片 if (pfDataGrid.SelectedItem != null) { var selectedItem = pfDataGrid.SelectedItem as ProofreadListModel; if (selectedItem != null) { selectedItem.ImagePath = filePath; // 使用高保真方式保存原始图片 using (FileStream fileStream = new FileStream(filePath, FileMode.Create)) { PngBitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(clipboardImage)); //使用原始剪贴板图片 encoder.Save(fileStream); } // 检查ImagePath是否存在 if (!string.IsNullOrEmpty(selectedItem.ImagePath) && File.Exists(selectedItem.ImagePath)) { foreach (var item in pfDataGrid.ItemsSource) { var model = item as ProofreadListModel; if (model != null && model.ImagePath == selectedItem.ImagePath) { Dispatcher.Invoke(() => LoadImageIntoRichTextBox(selectedItem.ImagePath)); } } } else { // 如果没有图片,清空RichTextBox Dispatcher.Invoke(() => rtbImages3.Document.Blocks.Clear()); } } } else { rtbImages3.Document.Blocks.Clear(); MessageBox.Show("请先选择列表内相应的意见内容以关联截图"); } } catch (Exception ex) { MessageBox.Show($"图片粘贴失败: {ex.Message}"); } }); } /// <summary> /// 读取截图到富文本 /// </summary> /// <param name="imagePath"></param> private void LoadImageIntoRichTextBox(string imagePath) { try { // 创建BitmapImage BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.CacheOption = BitmapCacheOption.OnLoad; // 缓存图片,关闭流后仍可用 bitmap.UriSource = new Uri(imagePath); bitmap.EndInit(); // 计算缩放比例(与之前粘贴图片时的逻辑一致) double scaleRatio = Math.Min( MaxImageWidth / bitmap.PixelWidth, MaxImageHeight / bitmap.PixelHeight ); scaleRatio = Math.Min(scaleRatio, 1.0); // 确保放大 // 创建图像控件 var imageControl = new System.Windows.Controls.Image { Source = bitmap, Width = bitmap.PixelWidth * scaleRatio, Height = bitmap.PixelHeight * scaleRatio, Stretch = Stretch.Uniform, Margin = new Thickness(0, 5, 0, 5) }; // 创建容器 Border imageBorder = new Border { Child = imageControl, BorderBrush = Brushes.LightGray, BorderThickness = new Thickness(1), CornerRadius = new CornerRadius(4), Background = Brushes.White, Padding = new Thickness(2) }; // 创建InlineUIContainer InlineUIContainer container = new InlineUIContainer(imageBorder) { BaselineAlignment = BaselineAlignment.Center }; // 创建段落并添加图片 Paragraph para = new Paragraph(); para.Inlines.Add(container); // 添加到RichTextBox rtbImages3.Document.Blocks.Add(para); } catch (Exception ex) { MessageBox.Show($"图片加载失败: {ex.Message}"); } } /// <summary> /// 修改后-加载图片 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void lstImages4_MouseDoubleClick(object sender, MouseButtonEventArgs e) { var openFileDialog4 = new Microsoft.Win32.OpenFileDialog { Filter = "图片文件|*.png;*.jpg;*.jpeg;*.bmp", Multiselect = true, }; if (openFileDialog4.ShowDialog() == true) { var _imageCollection4 = new ObservableCollection<BitmapImage>(); foreach (var screenshotPath in openFileDialog4.FileNames) { try { var bitmap = new BitmapImage(new Uri(screenshotPath)); bitmap.CacheOption = BitmapCacheOption.OnLoad; _imageCollection4.Add(bitmap); } catch { System.Windows.MessageBox.Show($"加载文件失败"); } lstImages4.ItemsSource = _imageCollection4; } } } /// <summary> /// 模型实体Model,程序数据和业务逻辑。 /// </summary> public class ProofreadListModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged;//2.属性改变的事件 protected void OnPropertyChanged(string propertyName)//3.激活事件的方法 { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } //标题样式声明(序列、意见内容、批注时间、修改状态、批注人员、问题性质) #region /// <summary> /// 序号 /// </summary> private int _serialNumber; public int SerialNumber { get { return _serialNumber; } set { _serialNumber = value; OnPropertyChanged(nameof(SerialNumber)); } } /// <summary> /// 意见内容 /// </summary> private string _opinionContent; public string OpinionContent { get { return _opinionContent; } set { _opinionContent = value; OnPropertyChanged(nameof(OpinionContent)); } } /// <summary> /// 批注时间 /// </summary> private string _annotationTime; public string AnnotationTime { get { return _annotationTime; } set { _annotationTime = value; OnPropertyChanged(nameof(AnnotationTime)); } } /// <summary> /// 修改状态 /// </summary> private string _modifyStatus; public string ModifyStatus { get { return _modifyStatus; } set { _modifyStatus = value; OnPropertyChanged(nameof(ModifyStatus)); } } /// <summary> /// 批注人员 /// </summary> private string _annotator; public string Annotator { get { return _annotator; } set { _annotator = value; OnPropertyChanged(nameof(Annotator)); } } /// <summary> /// 问题性质 /// </summary> private string _problemNature; public string ProblemNature { get { return _problemNature; } set { _problemNature = value; OnPropertyChanged(nameof(ProblemNature)); } } /// <summary> /// 图片路径 /// </summary> private string _imagePath; public string ImagePath { get { return _imagePath; } set { _imagePath = value; OnPropertyChanged(nameof(ImagePath)); } } #endregion } /// <summary> /// ViewModle中间参数桥梁 /// </summary> public class ProofreadListViewModel { public ObservableCollection<ProofreadListModel> DataItems { get; set; } = new ObservableCollection<ProofreadListModel>(); public ProofreadListViewModel() { } public void AddRange(List<ProofreadListModel> plms) { foreach (ProofreadListModel item in plms) { DataItems.Add(item); } } } } } 如何让Richtextbox中的文本和DataGridCell中的cell联动关联
最新发布
09-10
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慧香一格

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值