如何在呈现嵌套属性的 DataGridViewComboboxColumn 中禁用一个 ComboBox?

Posted

技术标签:

【中文标题】如何在呈现嵌套属性的 DataGridViewComboboxColumn 中禁用一个 ComboBox?【英文标题】:How to disable one ComboBox in a DataGridViewComboboxColumn where a nested property is presented? 【发布时间】:2017-11-10 12:55:07 【问题描述】:

我在 dataGridView 中显示对象列表。列表如下:

List<IAction> actions = new List<IAction>

我使用 karlipoppins 在 DataGridViewComboBoxColumn() 上显示了嵌套属性(未在 IAction 接口中定义) 此处回答(反射)Is it possible to bind complex type properties to a datagrid?

但是当一种对象中没有 Area 属性时,我无法禁用组合框

希望你能帮助我;)

列表中有两种类型的对象:

public class MoveAction : IAction
    
        public string Name  get; set; 
        public bool Active  get; set;  = true;
     

public class ClickAction : IAction
    
        public string Name  get; set; 
        public bool Active  get; set;  = true;
        public Area Area  get; set;   //////////  Additional Property
    

这个额外的属性对象看起来像:

public class Area

    public string Name  get; set; 
    ...

dataGridView 列定义如下:

    DataGridViewComboBoxColumn CreateComboBoxWithArea()
    
        DataGridViewComboBoxColumn combo = new DataGridViewComboBoxColumn();
        combo.DataSource = areas.Select(t => t.Name).ToArray();
        combo.DataPropertyName = "Area.Name";
        combo.Name = "Area";
        return combo;
    

【问题讨论】:

【参考方案1】:

我找到了自己的解决方案:

在投射发件人后,我可以访问整个网格。之后,我可以用这个组合框做我想做的事(隐藏按钮,设置只读...)。那是因为组合框没有属性 bool Enable ;/

感谢 jaredbaszler 的帮助!

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        
            DataGridView grid = (DataGridView)sender;
            DataGridViewRow row = grid.Rows[e.RowIndex];
            DataGridViewColumn col = grid.Columns[e.ColumnIndex];
            if (row.DataBoundItem != null && col.DataPropertyName.Contains("."))
            
                string[] props = col.DataPropertyName.Split('.');
                PropertyInfo propInfo = row.DataBoundItem.GetType().GetProperty(props[0]);
                if(propInfo != null)
                
                    object val = propInfo.GetValue(row.DataBoundItem, null);
                    for (int i = 1; i < props.Length; i++)
                    
                        propInfo = val.GetType().GetProperty(props[i]);
                        val = propInfo.GetValue(val, null);
                    
                    e.Value = val;
                
                else
                
                    DataGridViewCell cell = grid.Rows[e.RowIndex].Cells[e.ColumnIndex];
                    DataGridViewComboBoxCell chkCell = cell as DataGridViewComboBoxCell;
                    chkCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
                    cell.ReadOnly = true;
                
            
        

【讨论】:

【参考方案2】:

您可以绑定到单元格的BeginEdit 事件并在此时取消组合的编辑。喜欢:

dataGrid.CellBeginEdit += dataGrid_CellBeginEdit;

void dgSamples_CellBeginEdit(object sender, GridViewCellCancelEventArgs e)

    var areaObject = e.Row.Cells["Area"].Value AS Area; // .Value will be the current selected item in the cell's combo.
    if (areaObject.Area == null)
    
         e.Cancel = true;
    

这不会将组合显示为“已禁用”,但会阻止用户下拉组合并更改值。基本上使单元格只读。

最后,当您为组合框定义数据源时,我不确定您的 areas 列表对象是什么类型。所以当我将.Value 属性转换为Areas 时,我在猜测类型。你可能需要改变它。

【讨论】:

以上是关于如何在呈现嵌套属性的 DataGridViewComboboxColumn 中禁用一个 ComboBox?的主要内容,如果未能解决你的问题,请参考以下文章

在 Rails 中使用嵌套表单 - 如何使显示页面根据用户想要的呈现数量以表格格式显示每个新条目?

Scala Play:如何使用重复值和嵌套值呈现表单映射?

如何使用 jQuery 将 JSON 树呈现为使用 div 的嵌套 HTML?

如何从 JavaScript 对象呈现 HTML 中的嵌套列表?

如何呈现包含打开和未关闭标签的组件?反应.js

StackNavigator 不能嵌套多个级别?