One of the many great features in PIM Studio is the linked items panel that allows you to link a product to other products.
In addition to linking them, you can also edit these linked products.
For the linked items panel we provided a way so you can configure many different types of columns.
Out of the box we provide a variety of column types, but we know we will never be able to concieve and create all the customer specific cases.
To tackle that, we have created the linked items panel so you can create your own types of columns.
In this post we will provide a column that will show the category paths of each linked product.
We will also show you how to add this new type of column to an existing linked items panel.
This way we hope to give you a very simple example that will help you create all the customer specific columns you need.
Creating a column
There is one base class you must inherit from in order to add the column to the linked items panel.
It is a .NET base class that is used in the columns collection of a .NET GridView: System.Web.UI.WebControls.DataControlField.
When inheriting the DataControlField type you need to implement the abstract CreateField method:
| C# |
1
2
3
4
|
protected override DataControlField CreateField()
{
return new CategoryPathsField();
}
|
Only implementing the CreateField method will only get us a blank column.
If you want to add content you need to override the InitializeCell method.
The InitializeCell method is called each time a cell is created.
There is a small pitfall: this method is called for cells containing data but also for header and footer cells.
| C# |
1
2
3
4
5
6
7
8
9
10
11
12
|
public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
{
if (cellType == DataControlCellType.DataCell)
{
// when the cellType is DataCell, it means you are in a cell that is part of a data row
InitializeDataCell(cell);
}
else
{
base.InitializeCell(cell, cellType, rowState, rowIndex);
}
}
|
We now introduced a new method called InitializeDataCell which will create all the necessary setup for displaying something.
The method looks like this:
| C# |
1
2
3
4
5
6
7
8
9
10
|
private void InitializeDataCell(DataControlFieldCell cell)
{
// we create a Literal that will hold the category paths
Literal placeHolderForCategoryPath = new Literal();
placeHolderForCategoryPath.DataBinding += PlaceHolderForCategoryPath_DataBinding;
// add the Literal to the control collection of the cell
cell.Controls.Add(placeHolderForCategoryPath);
}
|
You might think "why are you hooking into the DataBinding method" and "why aren't you setting any value".
The reason is simple: there is no data item available when InitializeCell is called.
You can only access the data item when the DataBinding event is fired.
That's why we are hooking in to the DataBinding event.
When the DataBinding event is fired on the Literal placeholder, we will fetch the data item and retrieve the category paths.
| C# |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
private void PlaceHolderForCategoryPath_DataBinding(object sender, EventArgs e)
{
Literal placeHolderForCategoryPath = (Literal)sender;
// fetch the data item that we will visualize the category paths of
object dataItem = placeHolderForCategoryPath.Page.GetDataItem();
IEnumerable<Guid> categoryIds = GetCategoryIdsOfDataItem(dataItem);
IEnumerable<string> categoryLabelPaths = RetrieveLabelPaths(categoryIds);
// display the category label paths in the Literal
placeHolderForCategoryPath.Text = FormatLabelPathsForDisplay(categoryLabelPaths);
}
private IEnumerable<Guid> GetCategoryIdsOfDataItem(object dataItem)
{
Product product = dataItem as Product;
if (product == null)
{
return new Guid[0];
}
return product.Classifications.CopyManualClassificationIdsToArray();
}
private IEnumerable<string> RetrieveLabelPaths(IEnumerable<Guid> categoryIds)
{
CategoryHelper categoryHelper = new CategoryHelper(AdamContext.GetApplication());
IDictionary<Guid, LabelPath> labelPaths = categoryHelper.GetLabelPaths(categoryIds);
return labelPaths.Values.Select(x => x.ToString());
}
private string FormatLabelPathsForDisplay(IEnumerable<string> categoryLabelPaths)
{
StringBuilder formattedPaths = new StringBuilder();
foreach(string categoryLabelPath in categoryLabelPaths)
{
if (!string.IsNullOrEmpty(formattedPaths.ToString()))
{
formattedPaths.Append("<br/>");
}
formattedPaths.Append(HttpUtility.HtmlEncode(categoryLabelPath));
}
return formattedPaths.ToString();
}
|
To make things nicer we will add a header text to the column like this:
| C# |
1
2
3
4
5
6
7
8
9
10
11
|
public override string HeaderText
{
get
{
// always show "Category paths" as the header of the column
return "Category paths";
}
set
{
}
}
|
Allowing the column to be added to the LinkedItemsPanel
We now have a column that can be added to a GridView.
But we have to make sure that the column can be added to the xml configuration of the LinkedItemsPanel.
To do that, we must implement the Adam.Pims.UI.Controls.IConfigurableField interface.
The interface makes us implement two methods: Read and Write.
These two methods allow us to read and write xml configuration that is specific for this column.
If for instance you would like to be able to configure the header text of the column, these methods should be implemented.
In the Read method you would add code that reads the header text from the given xml element.
In the Write method you would add code that writes the header text in the given xml element.
Since we aren't doing anything special in this example, we do nothing in these methods:
| C# |
1
2
3
4
5
6
7
8
9
|
public void Read(XElement element)
{
// write code here in order to read configuration for this column from the element parameter
}
public void Write(XElement element)
{
// write code here in order to write the configuration of this column to the element parameter
}
|
Adding the column to the config of a LinkedItemsPanel
We still need to add a bit of xml to the configuration of linked items panel.
In the columns node of the xml setting you can add the following xml:
| XML |
1
|
<add type="Adam.Blog.Pims.CategoryPathsField, Adam.Blog.Pims" />
|
Make sure your custom dll is accessible
For PIM Studio to pick up on the class, it needs to be able to find your dll.
To be able to access your dll you can add the following things:
- Add dll to GAC
- Add dll to bin folder of website