You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何切换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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:13:45