Custom Control for DataGridTemplateColumn

自古美人都是妖i 提交于 2019-12-03 08:38:29
Philter

After fighting with this issue for a good deal of time I ended up creating a custom control that inherits from the DataGridBoundColumn in the PresentationFramework assembly. This works much better than trying to get the template properties to bind correctly. I believe they were not binding because the column template is not part of the visual tree. Based on what I see in the framework code it looks like what happens is the binding is passed off on to the cell that is generated. So the only real way to propagate the binding would be to use some kind of proxy object that does get data bound and have it map that binding to the dependency property. Very hacky.

I would suggest to future users to check out the DataGridTextColumn code on Microsoft's Reference Source. and build something similar for your own uses.

I ended up inheriting from the DataGridBound column for many of my custom controls. The key methods to pay attention to are GenerateEditingElement, GenerateElement and PrepareCellForEdit. They are all event handlers and allow you to manipulate the presentation of the cell as well as attach bindings and event handlers.

As an example here is a chunk of code from my custom DataGridDateColumn, as there is no built-in one and I wanted a reusable version with specific behavior for my application:

    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
    {
        DatePicker dp = new DatePicker();
        dp.Name = "datePicker";
        CustomControlHelper.ApplyBinding(dp, DatePicker.SelectedDateProperty, this.Binding);
        dp.PreviewKeyDown += DatePicker_OnPreviewKeyDown;
        return (FrameworkElement)dp;
    }

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
    {
        TextBlock tb = new TextBlock();
        CustomControlHelper.ApplyBinding(tb, TextBlock.TextProperty, this.Binding);            
        cell.TextInput += OnCellTextInput;            
        return (FrameworkElement)tb;
    }

    protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
    {
        DatePicker picker = editingElement as DatePicker;
        DateTime newValue = DateTime.Today;

        if (picker != null)
        {
            DateTime? dt = picker.SelectedDate;
            if (dt.HasValue)
            {
                newValue = dt.Value;
            }

        }            

        picker.Focus();
        return newValue;
    }       

Here as Message shows, This look like a type conversion issue and for that what u can do is you can create a one valueconverter and can apply manually as and when require which will convert binded value to specific type you want and will server your purpose.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!