创建一个新的自定义列

我尝试创建自己的复选框列(替换默认值),以便稍后移动到更复杂的数据列,并且我有以下代码:

public class MyCheckBoxColumn : DataGridBoundColumn
{
    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
    {
        var cb = new CheckBox();
        var bb = this.Binding as Binding;
        var b = new Binding { Path = bb.Path, Source = cell.DataContext };
        cb.SetBinding(ToggleButton.IsCheckedProperty, b);
        return cb;
    }

    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
    {
        var cb = new CheckBox();
        var bb = this.Binding as Binding;
        var b = new Binding { Path = bb.Path, Source = ToggleButton.IsCheckedProperty };
        cb.SetBinding(ToggleButton.IsCheckedProperty, b);
        return cb;
    }

    protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
    {
        var cb = editingElement as CheckBox;
        return cb.IsChecked;
    }

    protected override void CancelCellEdit(FrameworkElement editingElement, object uneditedValue)
    {
        var cb = editingElement as CheckBox;
        if (cb != null) cb.IsChecked = (bool)uneditedValue;
    }

    protected override bool CommitCellEdit(FrameworkElement editingElement)
    {
        var cb = editingElement as CheckBox;
        BindingExpression binding = editingElement.GetBindingExpression(ToggleButton.IsCheckedProperty);
        if (binding != null) binding.UpdateSource();
        return true;// base.CommitCellEdit(editingElement);
    }
}

我的自定义DataGrid:

public class MyDataGrid : DataGrid
{
    protected override void OnAutoGeneratingColumn(DataGridAutoGeneratingColumnEventArgs e)
    {
        try
        {
            var type = e.PropertyType;
            if (type == typeof(bool))
            {
                var col = new MyCheckBoxColumn();
                col.Binding = new Binding(e.PropertyName) {Mode = BindingMode.TwoWay};
                e.Column = col;
            }
            else
            {
                base.OnAutoGeneratingColumn(e);
            }
            var propDescr = e.PropertyDescriptor as System.ComponentModel.PropertyDescriptor;
            e.Column.Header = propDescr.Description;
        }
        catch (Exception ex)
        {
            Utils.ReportException(ex);
        }
    }
}

现在,除了两件事情之外,一切似乎都很好:

  • 似乎MyCheckBoxColumn唯一使用的方法是GenerateElement() 。 所有其他方法都没有使用。 我已经在它们中加入了断点,并且它们从未被击中......
  • 我使用ObservableCollection作为数据源,而其余列在通知我时会通知我,但这不是。
  • 奇怪的是,当您检查/取消选中复选框时, bool值会发生变化,但没有通知,也不会通过CommitCellEdit() 。 有人知道这里出了什么问题吗?

    编辑:

    看起来,如果我从GenerateElement()返回一个TextBlock ,它会调用其他方法(但通知问题不会被修复)。 但为什么这不与CheckBoxes一起使用? 默认复选框列如何工作?


    好。 以下是自定义CheckBox列的完整代码。 看起来,为了让一个控件像复选框一样在DataGrid中显示(而不是编辑)元素,你必须使它不可见。 或者您可以简单地使用TextBlock来显示一些类似于复选标记的字符:

    public class MyCheckBoxColumn : DataGridBoundColumn
    {
        protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
        {
            var cb = new CheckBox() { IsHitTestVisible = false, HorizontalAlignment = HorizontalAlignment.Center, HorizontalContentAlignment = HorizontalAlignment.Center };
            var bb = this.Binding as Binding;
            var b = new Binding { Path = bb.Path, Source = dataItem, Mode = BindingMode.TwoWay };
            cb.SetBinding(ToggleButton.IsCheckedProperty, b);
            return cb;
    //          var cb = new TextBlock() { TextAlignment = TextAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center };
    //          var bb = this.Binding as Binding;
    //          var b = new Binding { Path = bb.Path, Source = dataItem, Mode = BindingMode.TwoWay, Converter = new MyBoolToMarkConverter() };
    //          cb.SetBinding(TextBlock.TextProperty, b);
    //          return cb;
        }
    
        protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
        {
            var cb = new CheckBox() { HorizontalAlignment = HorizontalAlignment.Center, HorizontalContentAlignment = HorizontalAlignment.Center };
            var bb = this.Binding as Binding;
            var b = new Binding { Path = bb.Path, Source = dataItem, Mode = BindingMode.TwoWay };
            cb.SetBinding(ToggleButton.IsCheckedProperty, b);
            return cb;
        }
    
        protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
        {
            var cb = editingElement as CheckBox;
            if (cb != null) return cb.IsChecked;
            return false;
        }
    
        protected override void CancelCellEdit(FrameworkElement editingElement, object uneditedValue)
        {
            var cb = editingElement as CheckBox;
            if (cb != null) cb.IsChecked = (bool)uneditedValue;
        }
    
        protected override bool CommitCellEdit(FrameworkElement editingElement)
        {
            // The following 2 lines seem to help when sometimes the commit doesn't happen (for unknown to me reasons).
            //var cb = editingElement as CheckBox;
            //cb.IsChecked = cb.IsChecked;
            BindingExpression binding = editingElement.GetBindingExpression(ToggleButton.IsCheckedProperty);
            if (binding != null) binding.UpdateSource();
            return true;// base.CommitCellEdit(editingElement);
        }
    }
    //--------------------------------------------------------------------------------------------
    public class MyBoolToMarkConverter : IValueConverter
    {
        const string cTick = "■";
    
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value.GetType() != typeof(bool)) return "";
            bool val = (bool)value;
            return val ? cTick : "";
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value.GetType() != typeof(string)) return false;
            string val = (string)value;
            return val == cTick;
        }
    }
    //--------------------------------------------------------------------------------------------
    
    链接地址: http://www.djcxy.com/p/72475.html

    上一篇: Creating a new custom Column

    下一篇: Is it possible to create an URL pointing to an in