I have DataGrid with ObservableCollection of My class type as DataSource. I'm using a few TemplateColumns with the same DataTemplate so i got an idea that I create class for that column. The problem is that I don't know how to Bind data in that case.
My class obviously extends DataGridTemplateColumn
public class WindowedColumn : DataGridTemplateColumn
Also i have properties
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(Binding), typeof(WindowedColumn), new PropertyMetadata(null));
public static readonly DependencyProperty MaxLengthProperty =
DependencyProperty.Register("MaxLength", typeof(Binding), typeof(WindowedColumn), new PropertyMetadata(null));
public Binding Text
{
get { return (Binding)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public Binding MaxLength
{
get { return (Binding)GetValue(MaxLengthProperty); }
set { SetValue(MaxLengthProperty, value); }
}
My constructor code:
BindingOperations.SetBinding(this, FrameworkElement.DataContextProperty, new Binding
{
RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DataGrid), 1)
});
var standardTemplate = new DataTemplate();
var standardTextBlock = new FrameworkElementFactory(typeof(TextBlock));
standardTextBlock.SetBinding(TextBlock.TextProperty, Text);
standardTemplate.VisualTree = standardTextBlock;
DataTemplate editingTemplate = new DataTemplate();
var editingStackPanel = new FrameworkElementFactory(typeof(StackPanel));
editingStackPanel.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
var editingTextBox = new FrameworkElementFactory(typeof(TextBox));
editingTextBox.SetBinding(TextBox.TextProperty, Text);
//editingTextBox.SetBinding(TextBox.MaxLengthProperty, MaxLength);
editingTextBox.SetValue(TextBox.MinWidthProperty, 50.0);
editingTextBox.SetValue(TextBox.MaxWidthProperty, 200.0);
var editingButton = new FrameworkElementFactory(typeof(Button));
editingButton.SetValue(ContentControl.ContentProperty, ":");
editingStackPanel.AppendChild(editingTextBox);
editingStackPanel.AppendChild(editingButton);
editingTemplate.VisualTree = editingStackPanel;
CellTemplate = standardTemplate;
CellEditingTemplate = editingTemplate;
in my xaml file i use it like that
<Columns:WindowedColumn Header="My Column" Text="{Binding OrderNumber}" MaxLength="{Binding MyMaxLengthProperty}"/>
Visual shows me in xaml that no dataContext found for OrderNumber and of course when I run the program I don't see any value which i see in other TextColumn with the same binding for test
I found the solution. If anyone ever want to create custom column and use ItemsSource for DataGrid should know that data are store in rows not in DataGrid so you can't relate to DataContext at DataGrid. You should relate to DataContext in DataGridRow. Here is example how it can works:
You should also create columns after property change event like that
Constructor can be simplified to