Working with control templates in code is hard.
In WPF the standard and effective way is to create your template layout in XAML. And then if you need to pass any data to your controls you use Data Binding. You shouldn't normally need to construct templates in code except for rare circumstances.
To get the same effect you intended above using XAML you write:
<DataGrid x:Name="dataGrid1">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="file:///C:\abc.png" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
If the image path has to be dynamic for every grid row you can modify it like this:
<DataGrid x:Name="dataGrid1" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding ImageFilePath}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
and here's an example code behind for populating the grid with some data:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<MyDataObject> list = new List<MyDataObject>();
list.Add(new MyDataObject() { ImageFilePath = new Uri("file:///c:\\abc.png") });
list.Add(new MyDataObject() { ImageFilePath = new Uri("file:///c:\\def.png") });
dataGrid1.ItemsSource = list;
}
}
public class MyDataObject
{
public Uri ImageFilePath { get; set; }
}