none
"Runtime Generating dataTemplate for CellTemplate of GridViewCollumn"

    Question

  •  

    Hi All,

     

    I am creating on class which is having list of data.

    This list of data i want to bind to gridview collumn using cellTemplate.

     

    my requirement is i have a list of data in follwing format.

    Data[20.0 , 98.0 , 89 ,876 ,77] and so on. this i can access using my class property.

     

    Now my requirement is such that

     

    Day1 Day2 Day3 Day 4 Day5

    ------------------------------------------

    20.0   98.0   89     876    77

    20.0   98.0   89     876    77

    20.0   98.0   89     876    77

     

    For these i am adding collumns at runtime by code. because no of it will be dynamic not fixed.

    i am creating runtime datatemplate and assigning to each each collumn.

     

    i got it almost... can you suggest me the way i can do binding to celltemplate element at runtime ?

     

    see my object is DayDetail which has property DayValue.

    i want to bind DayValue property in such a way that it should not repeat in other listview item row.

    in my case it's getting repeated for all the row as shown above..

     

    Please, help me solve this out.

     

     

    Thursday, December 27, 2007 2:13 PM

Answers

  • Oops, I should dismiss my previous statement, actually ListView + GridView can do the trick, here is the code:

    Code Block
    <Window x:Class="DynamicTemplateCreationEx.Window3"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window3" Height="300" Width="300">
    <
    Grid>
    <
    ListView Name="listView">
    <
    ListView.Resources>
    <
    DataTemplate x:Key="headerTemplate">
    <
    TextBlock Text="{Binding}"/>
    </
    DataTemplate>
    </
    ListView.Resources>
    <
    ListView.View>
    <
    GridView>
    <
    GridViewColumn DisplayMemberBinding="{Binding [0].DayValue}" Header="Day1"/>
    <
    GridViewColumn DisplayMemberBinding="{Binding [1].DayValue}" Header="Day2"/>
    <
    GridViewColumn DisplayMemberBinding="{Binding [2].DayValue}" Header="Day3"/>
    <
    GridViewColumn DisplayMemberBinding="{Binding [3].DayValue}" Header="Day4"/>
    <
    GridViewColumn DisplayMemberBinding="{Binding [4].DayValue}" Header="Day5"/>
    </
    GridView>
    </
    ListView.View>
    </
    ListView>
    </
    Grid>
    </
    Window>

    namespace DynamicTemplateCreationEx
    {
    public class DayDetail
    {
    public DayDetail(Double dayValue, String dayName)
    {
    DayValue = dayValue;
    DayName = dayName;
    }

    public String DayName
    {
    get;
    set;
    }

    public Double DayValue
    {
    get;
    set;
    }
    }

    public partial class Window3 : Window
    {
    public Window3()
    {
    InitializeComponent();
    List<DayDetail> dayDetails1 = new List<DayDetail>
    {
    new DayDetail(20.0, "Day1"),
    new DayDetail(98.0, "Day2"),
    new DayDetail(89, "Day3"),
    new DayDetail(876, "Day4"),
    new DayDetail(77, "Day5")
    };

    List<DayDetail> dayDetails2 = new List<DayDetail>
    {
    new DayDetail(25.0, "Day1"),
    new DayDetail(99.0, "Day2"),
    new DayDetail(39, "Day3"),
    new DayDetail(874, "Day4"),
    new DayDetail(87, "Day5")
    };

    List<DayDetail> dayDetails3 = new List<DayDetail>
    {
    new DayDetail(50.8, "Day1"),
    new DayDetail(97.0, "Day2"),
    new DayDetail(39, "Day3"),
    new DayDetail(834, "Day4"),
    new DayDetail(67, "Day5")
    };

    List<List<DayDetail>> data = new List<List<DayDetail>> { dayDetails1, dayDetails2, dayDetails3 };
    listView.ItemsSource = data;
    }
    }
    }

    Hope this helps

    Wednesday, January 2, 2008 4:54 AM

All replies

  •  

    Hi all,

    is there any way using which i can do binding at cell level in GridViewCollumn?

     

    Like in greidview collumn i can set my object and and using triggers i can manage cell display different for each collumn.

     

    I worked a lot on this but still not getting the exact what i want.

     

    Please, do help me if you have solution.

     

    Thanks !

    Thursday, December 27, 2007 2:26 PM

  • Can you please give some more info.... maybe an example of what you want to do...
    Friday, December 28, 2007 10:31 PM
  •  

    I am creating on class which is having list of data.

    This list of data i want to bind to gridview collumn using cellTemplate.

     

    my requirement is i have a list of data in follwing format.

    Data[20.0 , 98.0 , 89 ,876 ,77] and so on. this i can access using my class property.

     

    Now my requirement is such that

     

    Day1 Day2 Day3 Day 4 Day5

    ------------------------------------------

    20.0   98.0   89     876    77

    20.0   98.0   89     876    77

    20.0   98.0   89     876    77

     

    For these i am adding collumns at runtime by code. because no of it will be dynamic not fixed.

    i am creating runtime datatemplate and assigning to each each collumn.

     

    i got it almost... can you suggest me the way i can do binding to celltemplate element at runtime ?

     

    see my object is DayDetail which has property DayValue.

    i want to bind DayValue property in such a way that it should not repeat in other listview item row.

    in my case it's getting repeated for all the row as shown above..

     

    Please, help me solve this out.

    Sunday, December 30, 2007 10:09 AM
  • Each row of the ListView will have an inherent data context based on the ItemsSource of the ListView.  It appears that you are not binding to the row's data context, but rather to some explicit object. 

     

    We need to see the code that you're using to create the cell templates.  When you create the bindings for the cell templates, you are not setting a Source, right?  You are also not explicitly setting the DataContext on the cell templates, right?

    Sunday, December 30, 2007 10:29 AM
  • <!--  xaml -- DataTemplate to be applied in CellTemplate>

    <DataTemplate x:Key="labResultCellTemplate">

    <Grid Background="LightBlue" DataContext="{Binding}">

    <TextBlock x:Name="txtLabResultValue" Text="{Binding Path=Days/InvestigationValue}"/>

    </Grid>

    </DataTemplate>

    <!-- Here InvestigationValue is a property of Day Object which returns exact value. i.e. actual value / path of image etc. based on condition. -->

     

    C#

    lstDays.ItemsSource =investigations  ;

     

    // Where lstDays is a listview and investigation is a object having list i.e. multiple investigations

    // now each investigations will have multiple days which will be our columns. i. e. Day1, Day2,.... Dayn.

    // Each Day will have different values displayed in Cell based on conditions.

     

    then i am running loop for number of collumns there  i want to set DataContext of Grid which is a root control in DataTemplate for each Cell.

     

    GVC.CellTemplate = (DataTemplate)this.FindResource("labResultCellTemplate"); // where GVC is a collumn

     

    DependencyObject DO = ((DataTemplate) ((GridView)lstViewDays.View).Columns[j].CellTemplate).LoadContent();

    ((Grid)DO).DataContext = Investigations[0].Days[0];

     

    where Days is a List of Days for Each investigation and is exposed as a property of investigations class.

     

    and i am assigning investigations.Days to the dataContext of the grid within Datatemplate. and setting Cell Template for a perticular collumn to the above given DataTemplate labResultCellTemplate.  if this much is done then i can manage the cell display by firing triggers withing xaml.

     

    Requirement:-

    for e.g.

     

    Day1      Day2     Day3

    ----------------------------------

    investigation1             89          79        

     

    investigation2         image                  image

     

     

    heare each cell will have diff. values based on type of investigation and on the day it's recorded . someday if not recorded then it will be blank as in day3 for first investigationand day2 for 2nd investigation.

     

    Please , give me the Solutions to achive this, as i am trying this for a long period.

     

    Thanks Dr. !!

     

    Monday, December 31, 2007 6:42 AM
  • I don't think you can enable this type of scenario using the build ListView+GridView to get this desired result.

    I've created a sample of how to enable this type of binding using GridViewHeaderRowPresenter + Grid, GridViewHeaderRowPresenter is used to layout the column header, Grid is used to layout each data cell, here is the code:

    Code Block
    public class DoubleToGridLengthConverter : IValueConverter
    {
    #region IValueConverter Members

    public object Convert(Object value, Type targetType, Object parameter, CultureInfo culture)
    {
    Double doubleValue = Double.PositiveInfinity;
    Double.TryParse(value.ToString(), out doubleValue);
    return new GridLength(doubleValue, GridUnitType.Pixel);
    }

    public object ConvertBack(Object value, Type targetType, Object parameter, CultureInfo culture)
    {
    throw new NotImplementedException();
    }

    #endregion
    }

    public class DayDetail
    {
    public DayDetail(Double dayValue, String dayName)
    {
    DayValue = dayValue;
    DayName = dayName;
    }

    public String DayName
    {
    get;
    set;
    }

    public Double DayValue
    {
    get;
    set;
    }
    }

    public partial class Window1 : Window
    {
    public Window1()
    {
    InitializeComponent();

    // Initialize the data souce collection 3X5.
    List<DayDetail> dayDetails1 = new List<DayDetail>
    {
    new DayDetail(20.0, "Day1"),
    new DayDetail(98.0, "Day2"),
    new DayDetail(89, "Day3"),
    new DayDetail(876, "Day4"),
    new DayDetail(77, "Day5")
    };

    List<DayDetail> dayDetails2 = new List<DayDetail>
    {
    new DayDetail(25.0, "Day1"),
    new DayDetail(99.0, "Day2"),
    new DayDetail(39, "Day3"),
    new DayDetail(874, "Day4"),
    new DayDetail(87, "Day5")
    };

    List<DayDetail> dayDetails3 = new List<DayDetail>
    {
    new DayDetail(50.8, "Day1"),
    new DayDetail(97.0, "Day2"),
    new DayDetail(39, "Day3"),
    new DayDetail(834, "Day4"),
    new DayDetail(67, "Day5")
    };

    List<List<DayDetail>> data = new List<List<DayDetail>> { dayDetails1, dayDetails2, dayDetails3 };

    //Initliaze the top-level layout panel.
    DockPanel dockPanel = new DockPanel();

    //Inialiaze the GridViewHeaderRowPresenter, set it as the top child element of DockPanel.
    GridViewHeaderRowPresenter headerPresenter = new GridViewHeaderRowPresenter();
    DockPanel.SetDock(headerPresenter, Dock.Top);
    dockPanel.Children.Add(headerPresenter);

    // Initialize each GridViewColumn for each item identified by "DayName" property value.
    headerPresenter.Columns = new GridViewColumnCollection();
    for (Int32 i = 0; i < data[0].Count; i++)
    {
    GridViewColumn column = new GridViewColumn();
    column.Header = data[0][i].DayName;
    column.DisplayMemberBinding = new Binding("DayValue");
    headerPresenter.Columns.Add(column);
    }

    // Initiliaze the layout panel for layouting data items.
    Grid grid = new Grid();
    dockPanel.Children.Add(grid);
    DoubleToGridLengthConverter converter = new DoubleToGridLengthConverter();
    for (Int32 row = 0; row < data.Count; row++)
    {
    RowDefinition rd = new RowDefinition();

    // Make sure each row's height is consistent with header.
    Binding rowBinding = new Binding("ActualHeight");
    rowBinding.Source = headerPresenter;
    rowBinding.Converter = converter;
    rd.SetBinding(RowDefinition.HeightProperty, rowBinding);
    grid.RowDefinitions.Add(rd);
    }

    for (Int32 column = 0; column < data[0].Count; column++)
    {
    ColumnDefinition cd = new ColumnDefinition();

    // Make sure each column's width is consistent with header.
    Binding columnBinding = new Binding("ActualWidth");
    columnBinding.Source = headerPresenter.Columns[column];
    columnBinding.Converter = converter;
    cd.SetBinding(ColumnDefinition.WidthProperty, columnBinding);
    grid.ColumnDefinitions.Add(cd);
    }

    // Create container aka ContentControl for each data item, and layout them according to the [row, column] cell.
    for (Int32 row = 0; row < data.Count; row++)
    {
    for (Int32 column = 0; column < data[row].Count; column++)
    {
    ContentControl cc = new ContentControl();
    cc.HorizontalAlignment = HorizontalAlignment.Center;
    cc.VerticalAlignment = VerticalAlignment.Center;
    cc.DataContext = data[row][column];
    cc.SetBinding(ContentControl.ContentProperty, headerPresenter.Columns[column].DisplayMemberBinding);
    Binding templateBinding = new Binding();
    templateBinding.Source = headerPresenter.Columns[column].CellTemplate;
    cc.SetBinding(ContentControl.ContentTemplateProperty, templateBinding);
    Grid.SetColumn(cc, column);
    Grid.SetRow(cc, row);
    grid.Children.Add(cc);
    }
    }

    this.Content = dockPanel;

    }
    }


    The method shown above only support static data source collection (aka the collection whose dimension will remains the same)

    Hope this helps

    Tuesday, January 1, 2008 7:01 AM
  • Oops, I should dismiss my previous statement, actually ListView + GridView can do the trick, here is the code:

    Code Block
    <Window x:Class="DynamicTemplateCreationEx.Window3"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window3" Height="300" Width="300">
    <
    Grid>
    <
    ListView Name="listView">
    <
    ListView.Resources>
    <
    DataTemplate x:Key="headerTemplate">
    <
    TextBlock Text="{Binding}"/>
    </
    DataTemplate>
    </
    ListView.Resources>
    <
    ListView.View>
    <
    GridView>
    <
    GridViewColumn DisplayMemberBinding="{Binding [0].DayValue}" Header="Day1"/>
    <
    GridViewColumn DisplayMemberBinding="{Binding [1].DayValue}" Header="Day2"/>
    <
    GridViewColumn DisplayMemberBinding="{Binding [2].DayValue}" Header="Day3"/>
    <
    GridViewColumn DisplayMemberBinding="{Binding [3].DayValue}" Header="Day4"/>
    <
    GridViewColumn DisplayMemberBinding="{Binding [4].DayValue}" Header="Day5"/>
    </
    GridView>
    </
    ListView.View>
    </
    ListView>
    </
    Grid>
    </
    Window>

    namespace DynamicTemplateCreationEx
    {
    public class DayDetail
    {
    public DayDetail(Double dayValue, String dayName)
    {
    DayValue = dayValue;
    DayName = dayName;
    }

    public String DayName
    {
    get;
    set;
    }

    public Double DayValue
    {
    get;
    set;
    }
    }

    public partial class Window3 : Window
    {
    public Window3()
    {
    InitializeComponent();
    List<DayDetail> dayDetails1 = new List<DayDetail>
    {
    new DayDetail(20.0, "Day1"),
    new DayDetail(98.0, "Day2"),
    new DayDetail(89, "Day3"),
    new DayDetail(876, "Day4"),
    new DayDetail(77, "Day5")
    };

    List<DayDetail> dayDetails2 = new List<DayDetail>
    {
    new DayDetail(25.0, "Day1"),
    new DayDetail(99.0, "Day2"),
    new DayDetail(39, "Day3"),
    new DayDetail(874, "Day4"),
    new DayDetail(87, "Day5")
    };

    List<DayDetail> dayDetails3 = new List<DayDetail>
    {
    new DayDetail(50.8, "Day1"),
    new DayDetail(97.0, "Day2"),
    new DayDetail(39, "Day3"),
    new DayDetail(834, "Day4"),
    new DayDetail(67, "Day5")
    };

    List<List<DayDetail>> data = new List<List<DayDetail>> { dayDetails1, dayDetails2, dayDetails3 };
    listView.ItemsSource = data;
    }
    }
    }

    Hope this helps

    Wednesday, January 2, 2008 4:54 AM