Converting a customized "DataGridBoundColumn" solution to syncfusion
public class CustomBoundColumn : DataGridBoundColumn
{
public string TemplateName { get; set; }
protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
var binding = new Binding(((Binding)Binding).Path.Path) { Source = dataItem };
var content = new ContentControl { ContentTemplate = (DataTemplate)cell.FindResource(TemplateName) };
content.SetBinding(ContentControl.ContentProperty, binding);
return content;
}
protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
{
return GenerateElement(cell, dataItem);
}
}
Here's an example of how it's used:
private void GatherTableColumns(ObservableCollection
{
.Properties
.Select((x, i) => new { x.Name, Index = i })
.ToArray();
foreach (var property in objectA)
{
var binding = new System.Windows.Data.Binding(string.Format("Properties[{0}]", property.Index));
if (property.Name == "Name")
{
DataGrid.Columns.Add(new CustomBoundColumn()
{
Header = property.Name,
Binding = binding,
TemplateName = "TemplateA"
});
}
else
{
DataGrid.Columns.Add(new CustomBoundColumn()
{
Header = property.Name,
Binding = binding,
TemplateName = "TemplateB"
});
}
}
}
|
<syncfusion:SfDataGrid x:Name="sfdatagrid"
AutoGenerateColumns="False"
ItemsSource="{Binding OrdersDetails}"
AllowEditing="True"
ShowRowHeader="True">
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTextColumn HeaderText="Shippers.CompanyName"
MappingName="ShippersInfo[0].CompanyName"
UseBindingValue="True" />
<syncfusion:GridTemplateColumn
MappingName="ShippersInfo[0].ShipperID" syncfusion:FocusManagerHelper.WantsKeyInput= "True"
UseBindingValue="True">
<syncfusion:GridTemplateColumn.CellTemplate>
<DataTemplate >
<TextBlock Name="NameTextBlock" Text="{Binding ShippersInfo[0].ShipperID}" />
</DataTemplate>
</syncfusion:GridTemplateColumn.CellTemplate>
<syncfusion:GridTemplateColumn.EditTemplate>
<DataTemplate >
<TextBox Name="NameTextBlock" Text="{Binding ShippersInfo[0].ShipperID}"/>
</DataTemplate>
</syncfusion:GridTemplateColumn.EditTemplate>
</syncfusion:GridTemplateColumn>
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid> |
Attachment: SyncfusionWpf_ObsCol_d50eb284.zip
On analyzing further with your sample, we have found that you have specified the MappingName as Properties[0].GenericCellValue instead of DProperties[0].GenericCellValue. Also, in the XAML you have bind only the GenericCellValue as Path instead of what you have specified in the MappingName. This is the cause of irrelevant result.
We have highlighted the changes which we have done in the given sample and please find that from below.
|
XAML:
<Window.Resources>
<DataTemplate x:Key="NameTemplate">
<TextBlock Name="DrawingNameTextBlock" Text="{Binding Path=CountryName}" Background="Blue"/>
</DataTemplate>
<DataTemplate x:Key="NameTemplate2">
<StackPanel>
<TextBlock Name="DrawingNameTextBlock" Text="{Binding Path=DProperties[0].GenericCellValue}" Background="Blue"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="NameTemplate3">
<StackPanel>
<TextBlock Name="DrawingNameTextBlock1" Text="{Binding Path=DProperties[1].GenericCellValue}" Background="Blue"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
C#:
var binding = new System.Windows.Data.Binding(string.Format("DProperties[{0}]", country.Index));
string columnPropertyIndexBinding = (string.Format("DProperties[{0}]", country.Index));
string genericCellValue = (string.Format("DProperties[{0}].GenericCellValue", country.Index));
int fIndex = country.Index;
if (country.GenericColumnHeader == "CountryName")
{
var templateColumn = new GridTemplateColumn()
{
HeaderText = country.GenericColumnHeader,
MappingName = columnPropertyIndexBinding,
UseBindingValue = true
};
templateColumn.CellTemplate = Resources["NameTemplate"] as DataTemplate;
templateColumn.UseBindingValue = true;
CountryDataGrid.Columns.Add(templateColumn);
}
else if(country.Index == 0)
{
var templateColumn = new GridTemplateColumn()
{
HeaderText = country.GenericColumnHeader,
MappingName = genericCellValue,
UseBindingValue = true
};
templateColumn.UseBindingValue = true;
templateColumn.CellTemplate = Resources["NameTemplate2"] as DataTemplate;
CountryDataGrid.Columns.Add(templateColumn);
}
else if(country.Index == 1)
{
var templateColumn = new GridTemplateColumn()
{
HeaderText = country.GenericColumnHeader,
MappingName = genericCellValue,
UseBindingValue = true
};
templateColumn.UseBindingValue = true;
templateColumn.CellTemplate = Resources["NameTemplate3"] as DataTemplate;
CountryDataGrid.Columns.Add(templateColumn);
} |
Please find the modified sample from the below link.
Sample link:
http://www.syncfusion.com/downloads/support/forum/139102/ze/SyncfusionWpf_ObsCol1109904637.zip
Please let us know if you have any other questions.
Regards,
Deivaselvan
We have modified the given sample by creating the DataTemplate in code behind using FrameworkElementFactory and it is used as the CellTemplate of TemplateColumn. Please find the changes from below.
|
private void BuildDataGridColumnTypesFromObsCollectionOfCountryData(ObservableCollection<CountryData> groupedCollection)
{
foreach (var country in groupedCollection.First()
.DProperties
.Select((x, i) => new { x.GenericColumnHeader, x.GenericCellValue, Index = i })
.ToArray())
{
var binding = new System.Windows.Data.Binding(string.Format("DProperties[{0}]", country.Index));
string columnPropertyIndexBinding = (string.Format("DProperties[{0}]", country.Index));
string genericCellValue = (string.Format("DProperties[{0}].GenericCellValue", country.Index));
int fIndex = country.Index;
if (country.GenericColumnHeader == "CountryName")
{
var templateColumn = new GridTemplateColumn()
{
HeaderText = country.GenericColumnHeader,
MappingName = columnPropertyIndexBinding,
UseBindingValue = true
};
templateColumn.CellTemplate = Resources["NameTemplate"] as DataTemplate;
templateColumn.UseBindingValue = true;
CountryDataGrid.Columns.Add(templateColumn);
}
else
{
var templateColumn = new GridTemplateColumn()
{
HeaderText = country.GenericColumnHeader,
MappingName = genericCellValue,
UseBindingValue = true
};
templateColumn.UseBindingValue = true;
var factory = new FrameworkElementFactory(typeof(TextBlock));
factory.SetBinding(TextBlock.TextProperty, new Binding(genericCellValue));
factory.SetValue(TextBlock.BackgroundProperty, System.Windows.Media.Brushes.Blue);
templateColumn.CellTemplate = new DataTemplate { VisualTree = factory };
CountryDataGrid.Columns.Add(templateColumn);
}
}
} |
Sample link:
http://www.syncfusion.com/downloads/support/forum/139102/ze/SyncfusionWpf_ObsCol-2050564780.zip
Regards,
Deivaselvan
We are glad to know that the provided solution met your requirement. Please let us know if you need any other assistance.
Regards,
Deivaselvan
- 7 Replies
- 3 Participants
-
RE Read
- Aug 6, 2018 04:25 AM UTC
- Aug 13, 2018 10:34 AM UTC