Search code examples
c#wpfwpfdatagriddatagridtemplatecolumn

selection change in wpf template combo box column changes values in other rows


In my project I have a data grid with three combo box template columns and are data bound to three collections and these columns are editable. The collection in the second and third combo box is selected based on the selected index of the combo box in first column when I change selection in first column in any row the change is reflected in all rows. here is my xaml code

<DataGrid x:Name="dtg"
              Grid.Row="2"
              AutoGenerateColumns="False"
              CanUserAddRows="True"
              IsReadOnly="False"
              VerticalScrollBarVisibility="Visible"
              EnableRowVirtualization="False"
              SelectionUnit="CellOrRowHeader"
              SelectionMode="Extended"
              ItemsSource="{Binding MainDataCollection, Mode= TwoWay}"
              AlternatingRowBackground="{DynamicResource AccentColorBrush2 }"
              GridLinesVisibility="Horizontal"
              KeyUp="Dtg_OnKeyUp" >
        <DataGrid.Columns>
            <DataGridTextColumn x:Name="slnoColunColumn"
                                Header="slno."
                                IsReadOnly="True"
                                Width="75"
                                Binding="{Binding Mode=OneWay , Path = Slno}"></DataGridTextColumn>

            <DataGridTemplateColumn Header="Category" Width="*" x:Name="categoryColumn">


                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox x:Name="categoryBox"
                            IsEditable="True"
                            controls:TextBoxHelper.ClearTextButton="True"
                            controls:TextBoxHelper.SelectAllOnFocus="True"
                            controls:TextBoxHelper.Watermark="Category"
                            MaxDropDownHeight="125"
                            SelectionChanged="CategoryBox_OnSelectionChanged"
                            DisplayMemberPath="CategoryName"
                            SelectedValuePath="CategoryId"
                            ItemsSource="{Binding Path=DataContext.CategoriesCollection, 
                            RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            <DataGridTemplateColumn Header="Question" Width="*" x:Name="questionColumn">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox x:Name="questionBox"
                            IsEditable="True"
                            controls:TextBoxHelper.ClearTextButton="True"
                            controls:TextBoxHelper.SelectAllOnFocus="True"
                            controls:TextBoxHelper.Watermark="Question"
                            MaxDropDownHeight="125"
                            DisplayMemberPath="TheQuestion"
                            SelectedValuePath="QuestionID"
                            ItemsSource="{Binding Path = DataContext.QuestionsCollection, 
                            RelativeSource = {RelativeSource FindAncestor, AncestorType = DataGrid}}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            <DataGridTemplateColumn Header="Answer" Width="*" x:Name="AnswerColumn">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox x:Name="answerBox"
                            IsEditable="True"
                            controls:TextBoxHelper.ClearTextButton="True"
                            controls:TextBoxHelper.SelectAllOnFocus="True"
                            controls:TextBoxHelper.Watermark="Answer"
                            MaxDropDownHeight="125"
                            DisplayMemberPath="TheAnswer"
                            SelectedValuePath="AnswerID"
                            ItemsSource="{Binding Path = DataContext.AnswersCollection, 
                            RelativeSource = {RelativeSource FindAncestor, AncestorType= DataGrid}}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

        </DataGrid.Columns>
    </DataGrid>

anybody know why it is behaving like this. Can anyone find a solution to fix this

Method to add data

public void AddData()
    {
        if (MainDataCollection== null) MainDataCollection = new ObservableCollection<GridDataSource>();
        if (CategoriesCollection == null) CategoriesCollection = new ObservableCollection<Category>();
        if(QuestionsCollection == null) QuestionsCollection = new ObservableCollection<Question>();
        if(AnswersCollection == null) AnswersCollection = new ObservableCollection<Answer>();

        AddDataGridRow(0);
        var data = _dataProvider.GetCategoriesTable(0);

        foreach (DataRow row in data.Rows)
        {

                CategoriesCollection.Add(new Category(int.Parse(row[0].ToString()),row[1].ToString()));
        }

    }

method to add new data grid row

 public void AddDataGridRow(int slno)
    {
        MainDataCollection.Add(new GridDataSource(slno+1,"","",""));
    }

Method to get questions

public void GetQuestions(int categoryId)
    {
        if (QuestionsCollection == null)QuestionsCollection = new ObservableCollection<Question>();
        QuestionsCollection.Clear();
        var data = _dataProvider.GetQuestionsTable(categoryId);
        foreach (DataRow row in data.Rows)
        {
            QuestionsCollection.Add(new Question(int.Parse(row[0].ToString()),row[1].ToString()));
        }

        GetAnswers(categoryId);            
    }

Method to get answers

 public void GetAnswers(int categoryId)
    {
        if (AnswersCollection == null) AnswersCollection = new ObservableCollection<Answer>();
        AnswersCollection.Clear();
        var data = _dataProvider.GetAnswersTable(categoryId);
        foreach (DataRow row in data.Rows)
        {
            AnswersCollection.Add(new Answer(int.Parse(row[0].ToString()), row[1].ToString()));
        }

    }

combo box selection changed

private void CategoryBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ComboBox cb = sender as ComboBox;
        _mainWindowViewModel.GetQuestions((int)cb.SelectedValue);            
    }

Solution

  • Try adding this to all 3 comboboxes:

    IsSynchronizedWithCurrentItem="False"

    I'm guessing this has been solved on this site before :)