0

I have the following code in XAML:

<data:DataGridTemplateColumn>

   <data:DataGridTemplateColumn.CellTemplate>

      <DataTemplate>

         <Image x:Name="picture" Width="200" Height="130" Visibility="Visible"/> 

      </DataTemplate>

   </data:DataGridTemplateColumn.CellTemplate>

</data:DataGridTemplateColumn>

How would do I this in the code behind (C#), without using this XAML code?

EDIT:

Here is the solution I am using:

Creating a Silverlight DataTemplate in code

This lets me do exactly what I want.

Community
  • 1
  • 1
Jesse
  • 599
  • 2
  • 9
  • 23
  • Probably the problem is only in the DataTemplate. I would use something like XamlReader.Parse(). – vortexwolf Mar 09 '11 at 22:32
  • Is it at all possible to have two different types of objects in the DataTemplate? For instance, if I want both a Label AND an Image in the cell. – Jesse Mar 09 '11 at 22:47
  • Yes, it's possible by using Grid or any other panel, and after that you can put any number of controls inside the panel. Also here is my answer where I created DataGridTemplateColumn in code-behind: http://stackoverflow.com/questions/4254266/datagrid-cell-style-binding/4258484#4258484 . DataTemplate is parsed from XAML. – vortexwolf Mar 09 '11 at 22:55
  • Great, I was able to add a Label and Image using a Canvas; but now this is being applied to all rows on the column (because it is a template). It there a way to only apply this template to certain rows in the column, while having a separate template for other rows? – Jesse Mar 09 '11 at 23:06
  • You can't use two templates, but you can switch panels inside a single template. I've provided more details in the answer below. – vortexwolf Mar 10 '11 at 12:59

1 Answers1

0

For example, you have a simple DataGrid

    <sdk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}">
        <sdk:DataGrid.Columns>
            <sdk:DataGridTemplateColumn CellTemplate="{StaticResource ImageCellTemplate}"/>
        </sdk:DataGrid.Columns>
    </sdk:DataGrid>

If you want to have several templates applied to a single DataGridRow, you can change visibility of internal parts inside the template:

    <DataTemplate x:Key="ImageCellTemplate">
        <Grid>
            <StackPanel Orientation="Horizontal" Visibility="{Binding IsImageTemplate}">
                <Image Width="20" Height="20"/>
                <TextBlock Text="{Binding Title}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Visibility="{Binding IsTextBoxTemplate}">
                <TextBlock Text="{Binding Id}" Foreground="Red"/>
                <TextBox Text="{Binding Title}"/>
            </StackPanel>
        </Grid>
    </DataTemplate>

There is the part with Image and the part with TextBox that are bound to the properties of an item view model (IsImageTemplate and IsTextBoxTemplate respectively). They are mutually exclusive and panels will not cover each other.

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
        var items = new List<ItemViewModel>()
        {
            new ItemViewModel{Id = 1, Title="First", IsImage = true},
            new ItemViewModel{Id = 2, Title="Second", IsImage = false},
            new ItemViewModel{Id = 3, Title="Third", IsImage = false}
        };
        this.DataContext = new MainViewModel { Items = items };
    }
}

public class MainViewModel
{
    public List<ItemViewModel> Items { get; set; }
}

public class ItemViewModel
{
    public int Id { get; set; }
    public string Title { get; set; }
    public bool IsImage { get; set; }

    public Visibility IsImageTemplate
    {
        get { return (IsImage == true) ? Visibility.Visible : Visibility.Collapsed; }
    }

    public Visibility IsTextBoxTemplate
    {
        get { return IsImage == false ? Visibility.Visible : Visibility.Collapsed; }
    }
}
vortexwolf
  • 13,967
  • 2
  • 54
  • 72