Search This Blog

Monday, November 21, 2011

C# change DataTemplate binding; C# change binding inside DataTemplate from code

 

The main idea is to have a DataTemplate in a separate XAML file but change Binding inside this DataTemplate from source code.
Create a xaml file, insert the DataTemplate and change Build action to: Embedded Resource (Copy to Output Directory: Do no copy - it is not necessary). The Assembly.GetManifestResourceStream() loads our resource as string. We can replace bindings then. XamlReader.Load() will convert string to DataTemplate. The Assembly.GetManifestResourceNames() will give you registered embedded resource name if something does not work.


DataTemplate mycolumnDataTemplate = null;
var dataTemplateStream = new ViewDescription().GetType().Assembly.GetManifestResourceStream("Some.Namespace.SomeReosurceName.xaml");
//Load the DataTemplate.
string dataTemplateString = new System.IO.StreamReader(dataTemplateStream).ReadToEnd();
dataTemplateString = dataTemplateString.Replace("[0]", browserColumn.ColumnName);
mycolumnDataTemplate = XamlReader.Load(dataTemplateString) as DataTemplate;

SomeReosurceName.xaml:

<DataTemplate
    x:Key="CustomDataGridColumnTemplate"
    xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <TextBlock Name="CustomTextBox" Text="{Binding [0]}" Margin="0,4,0,0"/>
</DataTemplate>

3 comments:

  1. Hello Bartosz

    Thanks for the post.
    This is a nice little article and I have a similar kind of situation where the service in application sends some collection of data and I have to construct the grid dynamically. Based on the datatype I have to load the template from a set of templates in the resource. However as I dont know column names during design time, I have to do the binding for the templates during runtime. I'm not able to get the template text to replace the binding column name.

    For e.g. I have 5 different templates in the resource and based on column datatype, I load the datatemplate from them (I use the this.Resources[resourcename] as DataTemplate). But for setting the binding, Im not able to get the text of the template.

    Any help will be highly appreciated.

    Thanks
    Jignesh

    ReplyDelete
    Replies
    1. From your comment I understand that you store DataTemplate inside Resources. My original solution was "text based" as I read the xaml file as TEXT and then used XamlReader.Load() to "convert" this string to a Data Template.

      From the beginning:
      - use Assembly.GetManifestResourceStream() to read xaml file as a stream.
      - replace [0] with a binding name
      - load string with XamlReader.Load() and you'll receive the data template you want.


      As for the second matter of receiving data from a service with uknown number of columns and columns names. We have constructed a "dynamic" Type using reflection (DataSet) which stores all the columns (with descriptions) and rows which can be later displayed in the DataGrid.

      Delete
  2. Bartosz

    Thanks for your reply. I have changed the way I load the template. Instead of loading the datatemplate from resources, I'm now creating the datatemplate in code (creating string for the template) and then loading that using XamlReader.Load method and it is working fine. As I said the column names are dynamic, so during run time, I'm generating a string will binding.

    Thanks again....

    ReplyDelete

If you like this post, please leave a comment :)