views:

619

answers:

1

Hi all i came across a problem with the checkboxes inside the datagrid.

First let me post my code of what i have achieved and then i will tell what's causing the trouble

This is the code of my datagrid inside a child window

<Controls:DataGrid x:Name="dgAthlete" Height="Auto" Width="Auto"
                                       IsReadOnly="True" AutoGenerateColumns="False"
                                       HorizontalAlignment="Stretch"
                                       HorizontalScrollBarVisibility="Disabled"
                                       ItemsSource="{Binding Data, ElementName=dds}"
                                   >
            <Controls:DataGrid.Columns>
                <Controls:DataGridTemplateColumn Header="CheckBoxColumn">
                    <Controls:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox  x:Name="cbAddAthlete"  IsChecked="{Binding IsAdded}" Tag="{Binding}"
                            IsEnabled="True" Checked="cbAddAthlete_Checked" Unchecked="cbAddAthlete_Unchecked" />
                        </DataTemplate>
                    </Controls:DataGridTemplateColumn.CellTemplate>
                    <Controls:DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding Path=IsAdded,Mode=TwoWay}"/>
                        </DataTemplate>
                    </Controls:DataGridTemplateColumn.CellEditingTemplate>
                </Controls:DataGridTemplateColumn>



                <Controls:DataGridTemplateColumn>
                    <Controls:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Image Source="{Binding ImageFileName}"
                                                Width="25" Height="25"
                                                HorizontalAlignment="Stretch" />
                        </DataTemplate>
                    </Controls:DataGridTemplateColumn.CellTemplate>
                </Controls:DataGridTemplateColumn>
                <Controls:DataGridTextColumn Header="FirstName" Binding="{Binding FirstName}" />
                <Controls:DataGridTextColumn Header="MiddleName" Binding="{Binding MiddleName}"/>
                <Controls:DataGridTextColumn Header="LastName" Binding="{Binding LastName}"/>
                <Controls:DataGridTextColumn Header="Email"  Binding="{Binding Email}" />
                <Controls:DataGridTextColumn Header="DOB" Binding="{Binding BirthDate}"/>
                <Controls:DataGridTextColumn Header="Phone" Binding="{Binding PhoneNumber}"/>
                <Controls:DataGridTextColumn Header="Website" Binding="{Binding WebSite}"/>
                <Controls:DataGridTextColumn Header="Team" Binding="{Binding TeamName}"/>
                <Controls:DataGridTextColumn Header="Club" Binding="{Binding ClubName}"/>
                <Controls:DataGridTextColumn Header="County" Binding="{Binding CountyName}"/>
            </Controls:DataGrid.Columns>
        </Controls:DataGrid>
        <Controls:DataPager x:Name="dpAthlete" PageSize="4"
                 HorizontalAlignment="Stretch" Source="{Binding Data, ElementName=dds}"
                 Width="Auto"/>
    </StackPanel>
    <Button x:Name="CancelButton" Content="Cancel" Click="CancelButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" />
    <Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="1" />

The code behind for this is

public partial class AddAthletesToCompetition : ChildWindow
{
    public ObservableCollection<Athlete> Athletes { get; set; }
    public int CompetitionId { get; set; }
    private PagedCollectionView pvcAthlete;

    public AddAthletesToCompetition(int competitionId)
    {
        InitializeComponent();
        CompetitionId = competitionId;
        LoadAthlete();
        Athletes = new ObservableCollection<Athlete>();

    }

    private void OKButton_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = true;
    }

    private void CancelButton_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = false;
    }
    private void LoadAthlete()
    {
        var context = new PublicServiceClient();
        context.GetAthletesNotInCompetitionCompleted += context_GetAthletesNotInCompetitionCompleted;
        context.GetAthletesNotInCompetitionAsync(CompetitionId);
    }

    void context_GetAthletesNotInCompetitionCompleted(object sender, GetAthletesNotInCompetitionCompletedEventArgs e)
    {
        if (e.Result != null)
        {
            pvcAthlete = new PagedCollectionView(e.Result.ToList());
            dgAthlete.ItemsSource = pvcAthlete;
            dpAthlete.Source = pvcAthlete;
        }
    }


    //Checkbox Checked Event Hanlder
    private void cbAddAthlete_Checked(object sender, RoutedEventArgs e)
    {
        var athlete = ((CheckBox)sender).Tag as AthleteBO;
        if (athlete != null)
        {
            var ath = new Athlete();
            ath.AthleteId = athlete.AthleteId;
            Athletes.Add(ath);
        }
    }


    //CheckBox unchecked Event Handler
    private void cbAddAthlete_Unchecked(object sender, RoutedEventArgs e)
    {
        var athlete = ((CheckBox)sender).Tag as AthleteBO;
        if (athlete != null)
        {
            var item = Athletes.First(i => i.AthleteId == athlete.AthleteId);
            Athletes.Remove(item);
        }
    }

}

As you can see i am using paging everything works fine i.e check and uncheck events for the checkbox work fine when we are on the first page but let's say you checked the first and the second item in the grid on the first page , now as soon as i go to the next page what my grid is doing its retaining the previous view and checking by default the first and the second item on the second page which is not expected behaviour

I went through various post on this issue and found that the problem is that the view is injected by the datagrid but somehow i couldn't find any solution.

What other's were talking about was refreshing the observable collection and again binding that to my grid.

So i was a little confused as where to bind that and when to update the observable collection.

I have posted whole of the code and whenever you reply please mention where exactly should i do the changes for this to work.

For a note i am using WCF and EF , so the list of athletes which i have here i will be sending this list to the WCF service where using EF it will be inserted into the database.

I know it's not a bug in Silverlight but this added feature of grid virtualization is causing a trouble with me currently so there should aslo be some solution to this problem.

Thanks

A: 

Add a IsSelected bool property to your entity and bind the checkbox control to it. This code sample looks like you are using .NET RIA services and the DomainDataSource (ItemsSource="{Binding Data, ElementName=dds}") control, not WCF? I have used this solution with WCF, but not in a paged setup. Give it a try and let us know how it turns out,

DaveB