Archive

Archive for the ‘Silverlight 4’ Category

Getting started with PivotViewer control

June 30, 2010 12 comments

Here is a basic walkthrough to get up and running with PivotViewer Control

After getting all the stuff as mentioned in the faq, Open VS2010 and create a silverlight application. Add a website hosted in IIS adding a clientAccesspolicy file as needed. Make sure it is set a startup project. Go the Property pages and select silverelightApplications and add a test page. set  the testpage as startup page. Make sure there are MimeTypes added in IIS for .cxml, .dzi and .dzc as “text/xml”

once you unzipped the tools,  you will find a docs folder in PAuthor folder. There is a sample.xlsx file. we will use that. The images are in the sample_images folder.

For simplicity, I copied everything in that folder to bin folder under PAuthor directory, If you are getting started, I would do the same, so we can get up and running without hiccups.

Go to command prompt to run the following command
Pauthor.exe /source excel sample.xlsx   /target deepzoom output\sample.cxml

one it is done in the “output” directory you will have “sample.cxml” and a folder “sample-deepzoom”. copy both of them to the website.

Now Add references to all the Pivot Assemblies from the folder “C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\PivotViewer\Jun10\Bin\”.  Not sure exactly which ones will be required as we are doing only minimal stuff.

open MainPage.xaml and add this namespace
xmlns:local=”clr-namespace:System.Windows.Pivot;assembly=System.Windows.Pivot”

Add the following XAML

 <Grid x:Name=”LayoutRoot” Background=”White”>
        <local:PivotViewer x:Name=”pv1″/>
    </Grid>

go to codebehind of the MainPage, after the line with InitializeComponent();

add the following line to load the collection. In my case the website name is “Mysample”
pv1.LoadCollection(“http://localhost/Mysample/sample.cxml“, null);

Now if you run the sample, you should have everything working

Categories: Silverlight 4 Tags:

RIA Services and Storedprocedures

May 24, 2010 18 comments

If we have a storedprocedure that we want to use to retrieve data and it returns an entity that is already in our model, it is pretty easy. Create a function import and indicate the type of object it returns and add a method in the domainservice to get the data

I am using Northwind database. I created a simple procedure to get the customers by city

create procedure GetCustomersByCity @city varchar(100) as

select * from Customers where City=@city

Created a Import(GetCustomersByCity) and added a method in the DomainService

 public IQueryable<Customer> GetCustomersByCity(string city)
    {
      return this.ObjectContext.GetCustomersByCity(city).AsQueryable<Customer>();
    }

and called like this
ctx.Load<Customer>(ctx.GetCustomersByCityQuery(“London”), (lo) => { dataGrid1.ItemsSource = lo.Entities; }, false);

it works fine

I tried to do the same using a existing procedure “CustOrderHist”

create PROCEDURE [dbo].[CustOrderHist] @CustomerID nchar(5)
AS
SELECT ProductName, Total=SUM(Quantity)
FROM Products P, [Order Details] OD, Orders O, Customers C
WHERE C.CustomerID = @CustomerID
AND C.CustomerID = O.CustomerID AND O.OrderID = OD.OrderID AND OD.ProductID = P.ProductID
GROUP BY ProductName

this doesnt return data that maps to any entity in our model. when I created a function import, I let it create a complexobject(CustOrderHistoryResult).

Then I added the following method similar to the one above in the DomainService

 public IQueryable<CustOrderHistoryResult> GetCustOrderHistory(string customerId)
    {
      return this.ObjectContext.CustOrderHistory(customerId).AsQueryable<CustOrderHistoryResult>();
    }

When I built the App, it gave me the following error

The entity ‘CustOrderHistoryResult’ in DomainService ‘NorthwindDomainService’ does not have a key defined.
Entities exposed by DomainService operations must have at least one public property marked with the KeyAttribute.

one way I got this to work is to add the following class in the Metadata.cs file of the DomainService, marking “ProductName” as the Key

[MetadataTypeAttribute(typeof(CustOrderHistoryResult.CustOrderHistoryResultMetadata))]
  public partial class CustOrderHistoryResult
  {

    internal sealed class CustOrderHistoryResultMetadata
    {
      private CustOrderHistoryResultMetadata()
      {

      }
      [Key]
      public string ProductName { get; set; }
      public int Total { get; set; }
    }
  }

after this I was able to call and get data from the procedure

ctx.Load<CustOrderHistoryResult>(ctx.GetCustOrderHistoryQuery(“ALFKI”), (lo) => { dataGrid2.ItemsSource = lo.Entities; }, false);

Not sure if this is the right way, but it seems to work

you can download the code here

RIA services and combobox lookups

May 3, 2010 18 comments

update: Here is another version using Async ctp, that will let us wait untill all the data for the related comboboxes is loaded.

Here is a quick sample on how to setup comboboxes for lookups whether in datagrid or dataform
I am using Chinook database which can be downloaded from here. I am using Employee and Customer tables only.
This sample uses for employee look up to populate the Support Rep ID column in the customer table

In Metadata class for the Customer, we add an attribute [Include] for the employee property
 public partial class Customer
  {
  
    internal sealed class CustomerMetadata
    {

      // Metadata classes are not meant to be instantiated.
      private CustomerMetadata()
      {
      }

     …

      [Include]
      public Employee Employee { get; set; }

     …
    }
  }

and in the DomainService, we include the Employee like below to fetech the related employee record for the customer

 [EnableClientAccess()]
  public class ChinookDomainService : LinqToEntitiesDomainService<ChinookEntities>
  {

    …

    public IQueryable<Customer> GetCustomers()
    {
      return this.ObjectContext.Customers.Include(“Employee”);
    }

    …
}

In XAML, we Add a DomainDataSource in the resources
<UserControl.Resources>
     <my1:DomainDataSource AutoLoad=”False” x:Name=”salesRepList” QueryName=”GetEmployeesQuery” LoadedData=”salesRepList_LoadedData”/>     
    </UserControl.Resources>

The DataGrid is defined like this

 <my:DataGrid x:Name=”datagrid1″ Grid.Row=”0″  AutoGenerateColumns=”False”>
            <my:DataGrid.Columns>
             <my:DataGridTextColumn Header=”FirstName”  Binding=”{Binding FirstName}”/>
             <my:DataGridTextColumn Header=”LastName”  Binding=”{Binding LastName}”/>
                <my:DataGridTextColumn Header=”City”  Binding=”{Binding City}”/>
                <my:DataGridTextColumn Header=”Country”  Binding=”{Binding Country}”/>
             <my:DataGridTextColumn Header=”Employee”  Binding=”{Binding Employee.FirstName}”/>
              
             <my:DataGridTemplateColumn Header=”Support Rep”>
              <my:DataGridTemplateColumn.CellTemplate>
               <DataTemplate>
                <TextBlock Text=”{Binding Employee.FirstName}”/>
               </DataTemplate>
              </my:DataGridTemplateColumn.CellTemplate>
              <my:DataGridTemplateColumn.CellEditingTemplate>
               <DataTemplate>
                <ComboBox ItemsSource=”{Binding Data, Source={StaticResource salesRepList}}”  SelectedValuePath=”EmployeeId”
                 DisplayMemberPath=”FirstName” SelectedValue=”{Binding SupportRepId, Mode=TwoWay}” />
               </DataTemplate>
              </my:DataGridTemplateColumn.CellEditingTemplate>
                   
             </my:DataGridTemplateColumn>
             <my:DataGridTemplateColumn Header=”Support Rep”>
              <my:DataGridTemplateColumn.CellTemplate>
               <DataTemplate>
                <TextBlock Text=”{Binding Employee.FirstName}”/>
               </DataTemplate>
              </my:DataGridTemplateColumn.CellTemplate>
              <my:DataGridTemplateColumn.CellEditingTemplate>
               <DataTemplate>
                <ComboBox ItemsSource=”{Binding Data, Source={StaticResource salesRepList}}”  SelectedItem=”{Binding Employee, Mode=TwoWay}”
                 DisplayMemberPath=”FirstName”  />

               </DataTemplate>
              </my:DataGridTemplateColumn.CellEditingTemplate>

             </my:DataGridTemplateColumn>
            </my:DataGrid.Columns>
        </my:DataGrid>

there are 2 Template columns defined. 1st column shows a way to specify the Id value (Foreign  Key) and the 2nd shows how to set the selectedItem

The codebehind looks like this

public partial class MainPage : UserControl
  {
    ChinookDomainContext ctx = new ChinookDomainContext();   
    public MainPage()
    {
      InitializeComponent();
      DomainDataSource ds = this.Resources["salesRepList"] as DomainDataSource;
      ds.DomainContext = ctx;
      ds.Load();
    }

    private void salesRepList_LoadedData(object sender, LoadedDataEventArgs e)
    {
      ctx.Load(ctx.GetCustomersQuery(), (lo) => {datagrid1.ItemsSource = lo.Entities;}, false);
    }
  
    private void Button_Click(object sender, RoutedEventArgs e)
    {
      ctx.SubmitChanges();
    }  
  }

you can download the sample from here

Drag and Drop grouping in Datagrid

April 25, 2010 10 comments

Most 3rd party components have a datagrid where you can a drag column header to the area above the grid to group the data. Here is one way to do the same with a regular datagrid

I am using SL4 and the latest Silverlight toolkit.
Here is my XAML, a Grid with 2 rows. In row 0 - a listbox where we drop the dragged columnheaders, in row 1 a Datagrid with columns defined

<Grid x:Name=”LayoutRoot” Background=”White” Height=”500″  Width=”400″>
        <Grid.RowDefinitions>
            <RowDefinition Height=”40″/>
            <RowDefinition Height=”*”/>           
        </Grid.RowDefinitions>
        <Grid  Grid.Row=”0″>
            <toolkit:ListBoxDragDropTarget AllowDrop=”True” Drop=”PanelDragDropTarget_Drop” Background=”#FFA74F4F”
                                           HorizontalContentAlignment=”Stretch” VerticalContentAlignment=”Stretch”>
                <ListBox x:Name=”list1″>
                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation=”Horizontal”/>
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Border BorderBrush=”Black” BorderThickness=”1″ >
                            <StackPanel Orientation=”Horizontal”  VerticalAlignment=”Center”>
                                <TextBlock Text=”{Binding}” Height=”20″/>
                                <Button Content=”x” Height=”20″  Margin=”5,0,0,0″ Click=”btn_Click” VerticalContentAlignment=”Top” />
                            </StackPanel>
                            </Border>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </toolkit:ListBoxDragDropTarget>        
        </Grid>
        <my:DataGrid x:Name=”datagrid1″ Grid.Row=”1″ AutoGenerateColumns=”False” Style=”{StaticResource DataGridStyle1}”>
            <my:DataGrid.Columns>
                <my:DataGridTextColumn Header=”Name”  Binding=”{Binding Name}”/>
                <my:DataGridTextColumn Header=”Title”  Binding=”{Binding Title}”/>
                <my:DataGridTextColumn Header=”City”  Binding=”{Binding City}”/>
                <my:DataGridTextColumn Header=”Country”  Binding=”{Binding Country}”/>
            </my:DataGrid.Columns>
        </my:DataGrid>       
    </Grid>

Next we need to allow the DataGridColumnHeaders to be draggable, so I grabbed the template of the datagrid, wrapped DataGridColumnHeadersPresenter in a PanelDragDropTarget like below. This is the only change in the template

<toolkit:PanelDragDropTarget Grid.Column=”1″ HorizontalContentAlignment=”Stretch”
 VerticalContentAlignment=”Stretch” AllowedSourceEffects=”Copy”>
 <sdk:DataGridColumnHeadersPresenter x:Name=”ColumnHeadersPresenter” AllowDrop=”True”   />
</toolkit:PanelDragDropTarget>

we handle the drop event to add the dragged item to the list of items we grouped with allowing the user to ungroup by clicking the button
 private void PanelDragDropTarget_Drop(object sender, Microsoft.Windows.DragEventArgs e)
        {
            // Retrieve the dropped data in the first available format.
            object data = e.Data.GetData(e.Data.GetFormats()[0]);
            DataGridColumnHeader dgch = ((data as ItemDragEventArgs).Data as SelectionCollection)[0].Item as DataGridColumnHeader;            
            list1.Items.Add(dgch.Content.ToString());           
            UpdateGroups();
        }

        void btn_Click(object sender, RoutedEventArgs e)
        {
            list1.Items.Remove((sender as Button).DataContext);
            UpdateGroups();
        }

        private void UpdateGroups()
        {
            if (pcv.GroupDescriptions != null)
                pcv.GroupDescriptions.Clear();

            list1.Items.ToList().ForEach(x =>
            {
                pcv.GroupDescriptions.Add(new PropertyGroupDescription { PropertyName = x.ToString() });
            }
            );
        }

you can download the code from here

Categories: Silverlight 4 Tags:

SL4(RC) RichTextBox and Access Violation

March 31, 2010 2 comments

update: looks like this has been fixed and will work fine in  RTW

There is  a  post in silverlight forums talking about listitem in RichTextBox and editing them.

I tried this

 <RichTextBox IsReadOnly=”True” >
            <Paragraph>
                <Run Text=”hello, this is a listbox”/>
                <LineBreak/>
                <InlineUIContainer>
                    <ItemsControl Margin=”10,0,0,0″>
                        <ListBoxItem >
                            <TextBox Text=”1. Item 1″/>
                        </ListBoxItem>
                        <ListBoxItem >
                            <TextBox Text=”2. Item 2″/>
                        </ListBoxItem>
                    </ItemsControl>
                </InlineUIContainer>
            </Paragraph>
        </RichTextBox>

As soon as I started editing the TextBox, got this error. looks like bug to me

Categories: Silverlight 4 Tags:

Summary rows in Datagrid with multiple groups

March 25, 2010 26 comments

Sometime back I posted one way to show the Summary/Totals in the group header and be able to resize individual columns when the columns are resized. That method has a limitation of not supporting nested groups. we can extend the same method to support multiple groups

Here are the steps.
we will start with what we had like in the previous sample.
1. we will add 1 GroupHeader style for each group we have. In my sample all the GroupHeader styles are same. One important change is there is a stackpanel in the GroupHeader named “ghsp” which hosts all the columns in the GroupHeader. we will add a Tag attribute and give a value of  “n-1″ when  “n” is the number of groups in the datagrid. if you have 3 groups then there will be 3 group header styles and Tag attribute  will be 2, 1, 0. This is how we can differentiate the different level group headers

2. The next change is in the Resize method. ” * 20″ is for resizing the column with groupname in the group header, 20 is roughly the size of indentation for each group (could be different if you change defaults in the template)

void Resize()
        {
            headers = datagrid1.GetChildrenByType<StackPanel>().Where(x => x.Name == “ghsp”).ToList();
            headers.ForEach(x =>
            {                
               (x.Children[0] as DataGridCell).Width = dghc.Children[1].RenderSize.Width + (Int32.Parse(x.Tag.ToString()) * 20) ;

                for (int i = 2; i < dghc.Children.Count – 2; i++)                                   
                    (x.Children[i - 1] as DataGridCell).Width = dghc.Children[i].RenderSize.Width;
               
            });
          
        }

3.  In the converter we have to change the way we get the totals from the CollectionViewGroup

private decimal GetProductTotal(CollectionViewGroup cvg)
        {
            decimal total = 0;
            int counter = 0;
            while (counter < cvg.Items.Count)
            {
                if (cvg.Items[counter] is CollectionViewGroup)
                    total += GetProductTotal(cvg.Items[counter] as CollectionViewGroup);
                else
                    total = (cvg.Items as IEnumerable<object>).Sum(x => (x as Product).Total);

                counter++;
            }
            return total;
        }

you can download the code from here

Categories: Silverlight 4 Tags:

PathListBox in SL4 – firstlook

March 17, 2010 4 comments

PathListBox is new in SL4 and  is in Microsoft.Expression.Controls.dll. It makes Path based layout easy. We could make nice menu buttons with little bit more styling to remove border of the listbox, the highlight color etc

The top part of the above image is just a plain listbox with items laid out horizontally

   <ListBox x:Name=”list1″ Margin=”30″ Grid.Row=”0″>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation=”Horizontal”/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>

The second listbox starts with the same, but uses PathListBox in the ItemTemplate.

<ListBox x:Name=”list2″ Margin=”30″ Grid.Row=”1″ FontSize=”8″>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation=”Horizontal”/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid  Margin=”15,0,15,0″>
                        <ec:PathListBox Margin=”0,0,0,0″ ItemsSource=”{Binding}” FontSize=”9.333″ ItemTemplate=”{StaticResource DataTemplate1}” FontWeight=”Bold” >
                            <ec:PathListBox.LayoutPaths>
                                <ec:LayoutPath   SourceElement=”{Binding ElementName=path}” Distribution=”Even” Start=”.8″   Orientation=”OrientToPath” Padding=”0″ Span=”0.5″ />
                            </ec:PathListBox.LayoutPaths>
                        </ec:PathListBox>
                        <Ellipse Width=”40″ Height=”40″ x:Name=”path” HorizontalAlignment=”Right” Margin=”0,25,0,0″>
                         <Ellipse.Fill>
                          <LinearGradientBrush EndPoint=”0.5,1″ StartPoint=”0.5,0″>
                           <GradientStop Color=”Black” Offset=”1″/>
                           <GradientStop Color=”White”/>
                          </LinearGradientBrush>
                         </Ellipse.Fill>
                        </Ellipse>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

 We start with placing a PathListbox, seting the itemssource to whatever string we are bound to and assigning it a LayoutPath which in this case is an ellipse and set few properties on the LayoutPath to customize the appearance.

Here is the codebehind to set the ItemsSource of the listbox

list2.ItemsSource = list1.ItemsSource = Enumerable.Range(0, 5).Select(x => “Option” + x.ToString());

Categories: Silverlight 4 Tags:

Summary row in DataGrid

February 1, 2010 75 comments

SummaryRow in DataGrid is one of the frequently asked request. Here  is one way we can customize the GroupHeader in Datagrid to create one

By default when we do grouping in the datagrid we get something like this

more often we need something like this.


Here are the steps
1.Add a style for the groupheader, In the above snapshot we see 4 columns, so we assume we need the Groupheader also to have 4 columns

We start by changing the existing GroupHeader Style. In the style, we see a stackPanel. we dont want this

  <StackPanel Grid.Column=”3″ Grid.Row=”1″ Orientation=”Horizontal” VerticalAlignment=”Center” Margin=”0,1,0,1″>
                        <TextBlock x:Name=”PropertyNameElement” Margin=”4,0,0,0″ Visibility=”{TemplateBinding PropertyNameVisibility}”/>
                        <TextBlock Margin=”4,0,0,0″ Text=”{Binding Name}” />
                        <TextBlock x:Name=”ItemCountElement” Margin=”4,0,0,0″ Visibility=”{TemplateBinding ItemCountVisibility}”/>
                    </StackPanel>

we will replace that stackpanel with this, we have to name it something so we can get to this when we want the cells to resize. We will add 4 controls in this case as we have 4 columns in the datagrid. Any control would work here, I went with datagridcell to keep them consitent with colors.
 <StackPanel x:Name=”ghsp” Orientation=”Horizontal”  Grid.Column=”3″ Grid.Row=”1″  VerticalAlignment=”Center” Margin=”0,1,0,1″>                                        
                                        <my:DataGridCell  Content=”{Binding Name}”/>                                                                               
                                        <my:DataGridCell  Content=””/>
                                        <my:DataGridCell HorizontalContentAlignment=”Right” Content=”{Binding Converter={StaticResource myConverter}, ConverterParameter=Orders}”/>
                                        <my:DataGridCell HorizontalContentAlignment=”Right” Content=”{Binding Converter={StaticResource myConverter}, ConverterParameter=Total,StringFormat=’{0:C}’}”/>                                       
                                    </StackPanel>
1st column is to display the name of the group, 2nd we dont want any summary in that, 3rd,4th will have the sum of orders and Totals
The rest of the xaml  is just styling the headers for right alignment, etc

The code in the converter looks like this

 public class MyConverter : IValueConverter
    {
        // This converts the DateTime object to the string to display.
        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            CollectionViewGroup cvg = value as CollectionViewGroup;
            string param = parameter as string;
            if (param == “Orders”)
                return cvg.Items.Sum(x => (x as Product).Orders);
            else
                return cvg.Items.Sum(x => (x as Product).Total);
        }

        // No need to implement converting back on a one-way binding
        public object ConvertBack(object value, Type targetType,
            object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

2.Binding the data

 products = new List<Product>();
 products.Add(new Product { Category = “Beverages”, Name = “Chai”, Orders = 110, Total = 648.00M });
 products.Add(new Product { Category = “Beverages”, Name = “Chai”, Orders = 120, Total = 259.20M });
 products.Add(new Product { Category = “Condiments”, Name = “Northwoods Cranberry Sauce”, Orders = 120, Total = 216.00M });
 products.Add(new Product { Category = “Condiments”, Name = “Grandma’s Boysenberry Spread”, Orders = 130, Total = 1200.00M });
 products.Add(new Product { Category = “Dairy Products”, Name = “Queso Cabrales”, Orders = 150, Total = 1400.00M });
 products.Add(new Product { Category = “Dairy Products”, Name = “Queso Manchego La Pastora”, Orders = 160, Total = 1280.00M });
 products.Add(new Product { Category = “Confections”, Name = “Pavlova”, Orders = 210, Total = 1500.00M });
 products.Add(new Product { Category = “Confections”, Name = “Teatime Chocolate Biscuits”, Orders = 114, Total = 800.00M });

 PagedCollectionView collectionViewSource = new PagedCollectionView(products);
 SortDescription sortDescription = new SortDescription(“Category”, ListSortDirection.Ascending);
 collectionViewSource.SortDescriptions.Add(sortDescription);
 GroupDescription groupDescription = new PropertyGroupDescription(“Category”);
 collectionViewSource.GroupDescriptions.Add(groupDescription);
 datagrid1.ItemsSource = collectionViewSource;

The above code is pretty standard, we need to add handlers so that the groupheader cells are resized when header cells of the datagrid

 datagrid1.LayoutUpdated += new EventHandler(datagrid1_LayoutUpdated);

 datagrid1.UnloadingRowGroup += (s, e) => { Resize(); };
 datagrid1.LoadingRowGroup += (s, e) => { refreshUI = true; };

 void datagrid1_LayoutUpdated(object sender, EventArgs e)
        {
            if (refreshUI && headers == null)
            {
                dghc = datagrid1.GetChildrenByType<DataGridColumnHeadersPresenter>().FirstOrDefault();
                foreach (DataGridColumnHeader dgch in dghc.Children)
                {
                    dgch.SizeChanged += (s, args) => { Resize(); };
                }
            }
            if (refreshUI)
                Resize();

            refreshUI = false;
        }

 void Resize()
 {
   headers = datagrid1.GetChildrenByType<StackPanel>().Where(x => x.Name == “ghsp”).ToList();
   headers.ForEach(x =>
   {               
      for (int i = 1; i < dghc.Children.Count – 2; i++)                                                      
         (x.Children[i - 1] as DataGridCell).Width = dghc.Children[i].RenderSize.Width;                                                                                  
   });
 }

what we are doing in the event handlers is, when the groups are loading/unloading or the datagrid is scrolled we adjust the width of the cells in the groupheader

3.If you look at the how the columns are defined in the datagrid

<my:DataGrid.Columns>
                <my:DataGridTextColumn Header=”Category” Binding=”{Binding Category}” Width=”Auto”/>
                <my:DataGridTextColumn  Header=”Name” Binding=”{Binding Name}” Width=”*”/>
                <my:DataGridTextColumn HeaderStyle=”{StaticResource headerStyle}” CellStyle=”{StaticResource cellStyle}” Header=”Orders” Binding=”{Binding Orders}” Width=”Auto” />
                <my:DataGridTextColumn  HeaderStyle=”{StaticResource headerStyle}” CellStyle=”{StaticResource cellStyle}” Header=”Total” Binding=”{Binding Total}” Width=”150″/>
                <my:DataGridTemplateColumn Header=””  Width=”Auto” Visibility=”Collapsed”>
                    <my:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock  />
                        </DataTemplate>
                    </my:DataGridTemplateColumn.CellTemplate>
                </my:DataGridTemplateColumn>
            </my:DataGrid.Columns>

There is an extra column at the end and Visibility=”Collapsed” is set. This is a hack as I could not get the last column to align right. If you dont have a summary column at the end. you dont need that.

you can download the code here

Categories: Silverlight 4 Tags: ,
Follow

Get every new post delivered to your Inbox.