views:

334

answers:

1

Hi, I was trying to figure this out for quite some time.I want a Databind a listbox with a Dataset.Simple as it can get.But my problem is that i want my datatemplate to display Columns from two tables,in the dataset.I have tried many samles..but everything i found just gives the dataset as datacontext and gives a single table as itemsource.But my condition is that i want more than one table in my datatemplate..

For eg:

<DataTemplate x:Key="EmployeeDataTemplate">
   <Grid>
      <Grid.ColumnDefinitions>
         <ColumnDefinition Width="60"/>
         <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
   <Border Margin="5" BorderBrush="Black" BorderThickness="1">
      <Image Source="{Binding Path=Mast/Image}" Stretch="Fill" Width="50" Height="50" />
   </Border>
   <StackPanel Grid.Column="1" Margin="5">
      <StackPanel Orientation="Horizontal" TextBlock.FontWeight="Bold" >
         <TextBlock Text="{Binding Path=Mast/Firstname}" />
         <TextBlock Text="{Binding Path=Mast/Lastname}" Padding="3,0,0,0"/>
      </StackPanel>
      <TextBlock Text="{Binding Path=Details/Age}" />
      <TextBlock Text="{Binding Path=Details/Role}" />
   </StackPanel>
  </Grid>
</DataTemplate>

Any way to do this..? I am confused...!

I tried giving the Dataset as datacontext and Itemsource as {Binding} But only one row is displayed...

A: 

You should create a view model class that exposes three properties:

  1. MasterTable of type IEnumerable<MasterTableRow>
  2. SelectedMaster of type DataRowView
  3. MasterDetails of type IEnumerable<DetailsTableRow>

In your view model, put your instance of your DataSet, and return the appropriate values for the properties. To wrap it all up, you should implement INotifyPropertyChanged and fire change notifications for SelectedMaster and MasterDetails whenever SelectedMaster changes.

Remember to set the view model as the DataContext for the bindings.

Here's how it might look like:

public partial class ViewModel : INotifyPropertyChanged
{
    DataSet1 ds;
    DataRowView selectedMaster;

    public IEnumerable<DataSet1.MasterTableRow> MasterTable
    {
        get { return ds.MasterTable; }
    }

    public DataRowView SelectedMaster
    {
        get { return selectedMaster; }
        set
        {
            if (selectedMaster != value)
            {
                selectedMaster = value;
                OnPropertyChanged("MasterDetails");
                OnPropertyChanged("SelectedMaster");
            }
        }
    }

    public IEnumerable<DataSet1.DetailsTableRow> MasterDetails
    {
        get
        {
            var masterRow = (DataSet1.MasterTableRow)SelectedMaster.Row;
            return masterRow.GetDetailsTableRows();
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string prop)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }

    #endregion
}

In XAML, the bindings might look like this:

<ListBox ItemsSource="{Binding MasterTable}" 
         SelectedItem="{Binding SelectedMaster}" 
         ItemTemplate="{StaticResource MasterTemplate}"/>
<ListBox ItemsSource="{Binding MasterDetails}" 
         ItemTemplate="{StaticResource DetailsTemplate}"/>
Aviad P.
thanks Aviad...I tried to do the same but i have some doubts.FIrst of all,i cant do this on a normal dataset right..? I guess i have to use a strogly typed datset..for eg an XSD instance.I tried to implement this with an xsd but i cant get through and i got some errors..In return masterRow.GetDetailsTableRows();I am getting error becasue GetDetailsTableRows() cannot be found.Am i doing things right..? Can i have a working sample..? Thanks in advance...
biju
Yes my example used a strongly typed dataset with a `MasterTable` and a `DetailsTable` you can modify the above sample to use a regular (non typed) dataset, by using `GetChildRows` and passing the relation.
Aviad P.