How to retrieve an element from a DataTemplate and bind to it?
I am trying to get a handle on an element within my DataTemplate in code. I am creating a series of DataGridTemplateColumns in code which I then assign to a grid. I want to be able to retrieve the DataTemplate from the xaml, find my element and bind to that particular element.
Here is a short sample code what I am trying to achieve:
<DataTemplate x:Key开发者_如何学JAVA="dataTemplate">
<Grid TextBlock.Foreground="LightGreen" Background="Yellow">
<TextBlock x:Name="txt" />
</Grid>
</DataTemplate>
DataGridTemplateColumn col = new DataGridTemplateColumn();
col.Header = "Last Name";
Binding b = new Binding("LastName");
DataTemplate dtemplate = (DataTemplate)FindResource("dataTemplate");
TextBlock textBlock = dtemplate.FindName("txt", this);
textBlock.SetBinding(TextBlock.TextProperty, b);
col.CellTemplate = dtemplate;
grid.Columns.Add(col);
Maybe to explain this further: I am trying to create a set of DataGridTemplateColumns on the fly and apply that to a Datagrid. Since I don't know the property to bind to until the time a source gets presented to me I cannot create a DataTemplate that nested within itself has this binding already build in. Like:
<TextBlock Text={Binding=LastName} ... >
So I am forced to create a set of DataGridTemplateColumn in runtime, look for DataTemplate in my resources and THEN try to bind that column to a property (like LastName) on my datasource.
I would approach this via CellStyle instead:
<DataGrid.Resources>
<Style x:Key="CellStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="TextBlock.Foreground" Value="LawnGreen"/>
<Setter Property="Background" Value="Yellow"/>
</Style>
</DataGrid.Resources>
DataGridTextColumn col = new DataGridTextColumn();
col.Binding = new Binding("Name");
col.CellStyle = dataGrid.Resources["CellStyle"] as Style;
dataGrid.Columns.Add(col);
There are also ways to do this via DataTemplates but it does not seem necessary in this case (unless your problem is more complex).
My solution to the problem is something like this:
GridView viewLayout = new GridView();
for (int i = 0; i < Apprefs.tables[0].Headers.Count(); i++)
{
GridViewColumn gvc = new GridViewColumn();
string colName = Apprefs.tables[0].Headers[i];
gvc.Header = colName;
gvc.Width = 80;
gvc.CellTemplate = SetTemplete(i); ;
viewLayout.Columns.Add(gvc);
}
listview1.View = viewLayout;
//set binding
listview1.ItemsSource = Apprefs.tables[0].Rows;
and then:
/// <summary>
/// Create DataTemplate
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
private DataTemplate SetTemplete(int i)
{
DataTemplate template = new DataTemplate();
//set stack panel
FrameworkElementFactory sp = new FrameworkElementFactory(typeof(StackPanel));
sp.Name = "spBind";
sp.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
//set textblock
FrameworkElementFactory tb = new FrameworkElementFactory(typeof(TextBlock));
sp.Name = "tbBind";
Binding b = new Binding();
string ito = "[" + i.ToString() + "]"; // bind by index
b.Path = new PropertyPath(ito);
tb.SetBinding(TextBlock.TextProperty, b);
sp.AppendChild(tb);
//set the visual tree of the data template
template.VisualTree = sp;
return template;
}
精彩评论