如何切换DevExpress LayoutControlItem的编辑器类型?
解决DevExpress LayoutControlItem编辑器类型双向切换的问题
我看了你的代码,问题主要出在这几个地方:
- 第一次切换到TextEdit后,原来的
searchLookUpEdit1已经被Dispose()销毁了,第二次切换时你再用它作为sourceEditor,其实是个已释放的对象,自然无法正确创建SearchLookUpEdit。 - 不同类型编辑器的
Properties是不同的派生类型(比如RepositoryItemTextEdit和RepositoryItemSearchLookUpEdit),直接用edit.Properties.Assign(sourceEditor.Properties)无法正确复制SearchLookUpEdit需要的核心属性(比如数据源、显示字段、值字段)。
这里给你修改后的代码,能稳定实现双向切换:
public partial class Form1 : DevExpress.XtraEditors.XtraForm { // 保存SearchLookUpEdit的核心配置,避免切换时丢失功能 private object _searchLookUpDataSource; private string _searchLookUpDisplayMember; private string _searchLookUpValueMember; public Form1() { InitializeComponent(); // 初始化时先保存SearchLookUpEdit的关键配置 _searchLookUpDataSource = searchLookUpEdit1.Properties.DataSource; _searchLookUpDisplayMember = searchLookUpEdit1.Properties.DisplayMember; _searchLookUpValueMember = searchLookUpEdit1.Properties.ValueMember; } private void checkEdit1_CheckedChanged(object sender, EventArgs e) { if (checkEdit1.Checked) { // 切换为TextEdit SwitchToTextEdit(layoutControlItem1); } else { // 切换回SearchLookUpEdit SwitchToSearchLookUpEdit(layoutControlItem1); } } private void SwitchToTextEdit(LayoutControlItem layoutItem) { layoutItem.Owner.BeginUpdate(); try { var currentEdit = layoutItem.Control as BaseEdit; if (currentEdit == null) return; // 创建新的TextEdit并同步基础属性 var textEdit = new TextEdit(); textEdit.Location = currentEdit.Location; textEdit.Size = currentEdit.Size; textEdit.Parent = currentEdit.Parent; textEdit.Text = currentEdit.Text; // 替换布局项的控件 layoutItem.Control = textEdit; // 释放旧控件 currentEdit.Dispose(); } finally { layoutItem.Owner.EndUpdate(); } } private void SwitchToSearchLookUpEdit(LayoutControlItem layoutItem) { layoutItem.Owner.BeginUpdate(); try { var currentEdit = layoutItem.Control as BaseEdit; if (currentEdit == null) return; // 创建新的SearchLookUpEdit并恢复配置 var searchLookUpEdit = new SearchLookUpEdit(); searchLookUpEdit.Location = currentEdit.Location; searchLookUpEdit.Size = currentEdit.Size; searchLookUpEdit.Parent = currentEdit.Parent; // 恢复之前保存的核心配置 searchLookUpEdit.Properties.DataSource = _searchLookUpDataSource; searchLookUpEdit.Properties.DisplayMember = _searchLookUpDisplayMember; searchLookUpEdit.Properties.ValueMember = _searchLookUpValueMember; // 同步文本值 searchLookUpEdit.Text = currentEdit.Text; // 替换布局项的控件 layoutItem.Control = searchLookUpEdit; // 释放旧控件 currentEdit.Dispose(); } finally { layoutItem.Owner.EndUpdate(); } } }
关键改进点:
- 提前保存SearchLookUpEdit的核心配置(数据源、显示/值字段),确保切换回去时能恢复完整功能。
- 拆分切换逻辑,针对不同编辑器类型单独处理,避免通用方法中不同Properties类型赋值的兼容性问题。
- 每次切换时直接获取LayoutControlItem当前的控件,不再依赖初始的
searchLookUpEdit1变量(因为它第一次切换后已被销毁)。 - 使用
try-finally确保EndUpdate()一定会执行,避免LayoutControl卡在更新状态。
如果后续需要支持更多编辑器类型的切换,可以把保存配置的逻辑抽象成通用字典存储,但针对你的场景,上面的代码已经足够解决问题了。
内容的提问来源于stack exchange,提问作者Blustacko
相关产品推荐
相关产品推荐

