0
votes

In Silverlight 3, I am tring to produce a basic, populated DataGrid, but the DataGrid is displaying 4 empty rows.

The code snippets for the page.xaml and page.xaml.cs are below.

I think the data is correctly contained in e.Results, because when I step through the codebehind, the web service is returning the List correctly populated, e.Results shows a count of 4, and the DataGrid displays four empty rows. (I have not yet figured out how to see what exactly is in e.Results)

Here is the relevant code in page.xaml.cs:

void Page_Loaded(object sender, RoutedEventArgs e)
{
  Service1Client service = new Service1Client();
  service.GetAccountsCompleted += new
   EventHandler<GetAccountsCompletedEventArgs>(service_GetAccountsCompleted );
  service.GetAccountsAsync();

}

void service_GetAccountsCompleted(object sender, GetAccountsCompletedEventArgs e)
{
  this.grdData.ItemsSource = e.Result;
}

Here is the xaml definition of the DataGrid:

<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  x:Class="BegSilver.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
  <data:DataGrid x:Name="grdData"  Margin="15" AutoGenerateColumns="False">

  <data:DataGrid.Columns>

    <data:DataGridTextColumn Binding="{Binding acpk}" Header="acpk"></data:DataGridTextColumn>
    <data:DataGridTextColumn Binding="{Binding acctnumber}" Header="acctnumber"></data:DataGridTextColumn>
    <data:DataGridTextColumn Binding="{Binding name}" Header="name"></data:DataGridTextColumn>
    <data:DataGridTextColumn Binding="{Binding type}" Header="type"></data:DataGridTextColumn>

  </data:DataGrid.Columns>

</data:DataGrid>
</Grid>
</UserControl>

Any help would be greatly appreciated.

4
Are the 4 rows actually empty or perhaps is there something like foreground and background set the same. I have done that enough times. Also, it shouldn't matter, but those tags are self closing, so you can just use /> at the end rather than a closing tag. - Godeke

4 Answers

0
votes

I had the exact same problem. It turned out that the Foreground text color and background colors of the cells were the same. Just change those and you should be good. There's some examples here: http://silverlight.net/forums/t/42372.aspx

Add a foreground color style to your datagrid to see the text. Something like this:

<UserControl.Resources>
    <Style x:Key="gridStyle" TargetType="Controls:DataGrid">
        <Setter Property="Foreground" Value="Black" />
    </Style>
</UserControl.Resources>


<Controls:DataGrid x:Name="grid" AutoGenerateColumns="True" Style="{StaticResource gridStyle}">

...

0
votes

The column names are case sensitive. Are you sure it is

   Binding="{Binding acpk}"

and not

   Binding="{Binding Acpk}"
0
votes

You can't perform binding like that directly from e.Result.

<data:DataGridTextColumn Binding="{Binding acpk}" Header="acpk">
</data:DataGridTextColumn>

You're on the right track working with e.Result but you really should put the results into a collection then work with that. I know it's redundant but it seems that a collection of a collection or a list of a collection etc is how it's done the "Silverlight way"

Try something like this. Create a class. This will process your results when looping through e.Result.

public class Recording
{
  public Recording() { 
  }
  public Recording(string artistName, string cdName, DateTime release)
  { Artist = artistName; Name = cdName; ReleaseDate = release; }
  public string Artist { get; set; }
  public string Name { get; set; }
  public DateTime ReleaseDate { get; set; }
  // Override the ToString method.
  public override string ToString() 
  { 
    return Name + " by " + Artist + ", Released: " + ReleaseDate.ToShortDateString();
  }
} 

In the code behind where you have called your service create a collection. This will collect e.Result content and pass it to the class mentioned.

 public ObservableCollection<Recording> MyMusic   = new ObservableCollection<Recording>();

In the completed args event handler add something like this.

private void  service_GetAccountsCompleted(object sender, GetAccountsCompletedEventArgs e)
{
  foreach (var item in e.Result)
  {   
      MyMusic.Add(new Recording(item.acctnumber, item.acpk, new DateTime(2011, 4, 18)));
      grdData.DataContext = MyMusic;               
  }

I have used this for reference and I think it's worth a look. It shows how to bind in multiple ways and helped me when learning more about data binding. http://www.silverlight.net/learn/quickstarts/bindingtocontrols/

-1
votes

A guess here, but I would venture that rather than setting the itemssource property, you should be setting the DataContext property. ItemsSource is for collection based controls such as a ListBox etc, and is used to define what collection to use to populate the items.

My guess is that you populated an object (Account) from a WCF service
If so, set

this.grdData.DataContex= e.Result; in your GetAccountsCompleted handler

Good Post here sumarrizing the differences between ItemsSource and DataContext http://anyedotnet.blogspot.com/2008/11/datacontext-vs-itemssource.html