This post shows how to add button column to a datagrid(Silverlight) and react to the click event
1.Create a resource for the DataGridtemplateColumn, define CellTemplate
2.After setting the ItemsSource, get the resource we added in step 1 and add it to the grid
this is XAML from the page
<UserControl x:Class=”SilverlightApplication1.Page”
xmlns=”http://schemas.microsoft.com/client/2007”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
Width=”600″ Height=”600″
xmlns:data=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data”
xmlns:local=”clr-namespace:SilverlightApplication1;assembly=SilverlightApplication1″>
<UserControl.Resources>
<data:DataGridTemplateColumn Header=”” x:Name=”dtc”>
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Click=”Button_Click” Tag=”{Binding CustomerID}”
Content=”Delete”></Button>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
</UserControl.Resources>
<Canvas>
<data:DataGrid x:Name=”dataGrid1″
Height=”400″
Width=”450″
Margin=”0,5,0,10″
AutoGenerateColumns=”True” />
<TextBlock Text=”Sample Text” x:Name=”txt1″
Canvas.Top=”500″
Canvas.Left=”100″></TextBlock>
</Canvas>
</UserControl>
let’s say we are getting data from WCF service
the code to call WCF service will look something like this
BasicHttpBinding b = new BasicHttpBinding();
EndpointAddress addr = new EndpointAddress(“http://localhost/mywebsite/MyService.svc“);
ServiceReference1.MyServiceClient client = new SilverlightApplication1.ServiceReference1.MyServiceClient(b, addr);
client.GetCustomersCompleted += new EventHandler<SilverlightApplication1.ServiceReference1.GetCustomersCompletedEventArgs>(client_GetCustomersCompleted);
client.GetCustomersAsync();
void client_GetCustomersCompleted(object sender, SilverlightApplication1.ServiceReference1.GetCustomersCompletedEventArgs e)
{
this.dataGrid1.ItemsSource = e.Result;
//this gets the column from the resources and inserts at the beginning of the row
this.dataGrid1.Columns.Insert(0, this.Resources[“dtc”] as DataGridTemplateColumn);
}
// this button click handler sets the text of a Textblock(“txt1”) to customerid of the row in which the button is clicked
private void Button_Click(object sender, RoutedEventArgs e)
{
this.txt1.Text = (sender as Button).Tag.ToString();
}
Quite impressing !!!, XAML it’s a real modern markup language. Thanks for the tip.
Thanks Lee – the SelectionChanged handler is a pain in the butt, this gave me what I needed to sidestep it!
Same here…my row wouldn’t update the value if I clicked on a new row. This solved my problem.
I tried to use this to add click event handler using code below but got exception at Click=”Button_Click”:
Failed to assign to property ‘System.Windows.Controls.Primitives.ButtonBase.Click’
How to fix ?
Issue 2: In this code column name “PictureColumn” is hard coded. How to set column name in runtime (diffrent grids have different picture property names) ?
Andrus.
XAML:
….
C#:
partial class DataGridBase : DataGrid
{
void Create() {
DataGridTemplateColumn templateCol = new DataGridTemplateColumn();
templateCol.CellTemplate = (Resources[“dtc”] as DataGridTemplateColumn).CellTemplate;
Columns.Add(templateCol);
}
void Button_Click(object sender, RoutedEventArgs e) { }
}
XAML was removed from message. Below is xaml with tag characters removed:
data:DataGrid x:Class=”MyApp.Controls.DataGridBase”
xmlns:data=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data”
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
data:DataGrid.Resources
data:DataGridTemplateColumn Header=”” x:Name=”dtc”
data:DataGridTemplateColumn.CellTemplate
DataTemplate
Button Click=”Button_Click”
Image Source='{Binding PictureColumn, Converter={StaticResource myImageConverter}}’/
/Button
/DataTemplate
/data:DataGridTemplateColumn.CellTemplate
/data:DataGridTemplateColumn
….
Hi,
Do you have the click handler in the code behind?. Did you try to create the datatemplate in code and assign it, so that you could create the binding at runtime.
There is click handler in DataGridBase class as shown in code sample:
void Button_Click(object sender, RoutedEventArgs e) { }
If DataTemplate is created in code using XamlReader.Load exception occurs telling that click handler cannot set in string used as Load parameter. I dont know how to define CellTemplate directly in resource. So this sample code assigns resource form Xaml file using
(Resources[“dtc”] as DataGridTemplateColumn).CellTemplate
Hi,
Having the click handler in the base class would not work. that is the reason for exception.
xaml is in DataGridBase.xaml file.
Click handler is in DataGridBase.xaml.cs file.
This is like in your sample. So this shoud work.
Maybe assigning part using line (Resources[“dtc”] as DataGridTemplateColumn).CellTemplate
breaks this.
Hi,
if you are loading the datatemplate from a string and it has a event handler it will fail
I’m loading datatemplate from a resource, not from string:
DataGridTemplateColumn templateCol = new DataGridTemplateColumn();
templateCol.CellTemplate = (Resources[“dtc”] as DataGridTemplateColumn).CellTemplate;
Columns.Add(templateCol);
looks like that has the same effect as loading from a string. I guess you have to find another way of doing that
I created testcase for it. running solution from
http://cid-69f11148404c9c0e.office.live.com/self.aspx/.Public/clickhandlernotfoundinxaml.zip
Causes exception
Failed to assign to property ‘System.Windows.Controls.Primitives.ButtonBase.Click’.
How to fix ?
I tried take the eventhandler from xaml out and add a click event handler in the loadingrow event, I it is not going to the event handler. Not sure of any other options
I added click event handler in column creation code as described in http://forums.silverlight.net/forums/p/189927/439436.aspx Unfortunately click event handler is not executed for unknown reason.
That is what I tried as psoted in my previous comment.
Is this Silverlight bug that click event handler is not called ? How to fix this ?
I am not sure.
Hi Friends,
Please help me I am writing given method in SilverLight 3. but this method is not
Working properly where I am wrong? I have not more experience in silverlight.i think DataSet is not available in silverlight.
public class Search
{
public void bindDataGrid(DataGrid dg, XDocument xDoc, string DescendantsName)
{
if (xDoc.Descendants(DescendantsName).Count() > 0)
{
var Xel = from xe in xDoc.Descendants(DescendantsName) select xe;
foreach (var xe in Xel.Elements())
{
DataGridTextColumn col = new DataGridTextColumn();
col.Header = xe.Name.LocalName;
System.Windows.Data.Binding bnd = new
System.Windows.Data.Binding();
bnd.ConverterParameter = xe.Name.LocalName;
col.Binding = bnd;
dg.Columns.Add(col);
}
var result = new List();
foreach (var element in xDoc.Descendants(DescendantsName))
{
foreach (var column in element.Elements())
{
result.Add(column.Value);
}
}
dg.ItemsSource = result;
}
}
Parameters details:-
DataGrid dg, XDocument xDoc, string DescendantsName
My XDocument looks like this that I am trying to pass as parameter :-
0
9835496788
Active
DescendentsName is “ResponseData”.
I am trying to bind datagrid dynamically where IsB2B, MdnId & WalletStatus will be Columns of Datagrid and 0, 9835496788 & Active will be a single row (each value corresponding to it’s Column ) of the DataGrid.
My output is like this;-
But I want like this:-
Anup Kumar
Delhi,India.
Hi, Send me a sample with no dependencies, I will take a look
Do you mind if I quote a couple of your articles as
long as I provide credit and sources back to your website?
My blog site is in the exact same area of interest
as yours and my visitors would really benefit from some of the information you present here.
Please let me know if this alright with you.
Thanks!
Sure, Feel free