dvandamme
dvandamme

Reputation: 26

Binding from DataGrid in DataTemplate to ObservableCollection of strings

So I have a WPF c# project, and inside a usercontrol, I have a list, which sets display of a collection through a DataTemplateSelector. Those databound objects that contains some simple strings and ints, as as well as an observable collection of strings called Answers. I've implemented INotifyPropertyChanged inside the object with the required PropertyChangedEventHandler and function.

So, heres the snippet of xaml that lives in the datatempate called to display the listItem

<DataGrid x:Name="AnswersListBox" HorizontalAlignment="Stretch" Grid.Column="3" Grid.Row="3" Grid.ColumnSpan="2" ItemsSource="{Binding Answers}"
  AutoGenerateColumns="False" Margin="10,10,10,10" CanUserResizeRows="False"  >
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Path=DataContext, 
             RelativeSource={RelativeSource Self}, Mode=TwoWay}" Header="Possible Answers"
             Width="130" IsReadOnly="False" CanUserResize="False" CanUserSort="False" CanUserReorder="False" MaxWidth="130"/>
    </DataGrid.Columns>
</DataGrid>

image showing the working data bound object

enter image description here

My issue is, the datagrid that shows the answers (currently has 'a word' repeated in it) wont update... ive tried a lot of variations for this with editable listview and listbox with text boxes, but this datagrid is the closest Ive gotten, except it won't keep an edited value inside that observerablecollection

edit to add more code

heres the ObserverableCollection

namespace CRUDeBuilder.chunkProtos
{
public class MultiChoice : Question
{
    /// <summary>
    /// this is a type of question that holds a statement and several answers
    /// </summary>

    private ObservableCollection<string> answers = new ObservableCollection<string>();
    private int correctAnswer = 0;
    private bool randomise = false;

    public MultiChoice()
    {
        base.QuestionType = "multiChoice";
    }


    public ObservableCollection<string> Answers
    {
        get
        {
            return answers;
        }
        set
        {
            answers = value;
            base.NotifyPropertyChanged("Answers");

        }

    }
// ive just chopped off bits here

The implementation of INotifyPropertyChanged is in the base class for Multichoice:Question and is

public abstract class Question : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }

}

the code behind that adds items to the answer observablecollection

private void addAnswerBtn_Click(object sender, RoutedEventArgs e)
    {
        Button button = sender as Button;
        Question question = button.DataContext as Question;


        //Console.WriteLine("clicking add answer button");
        if (question is MultiChoice)
        {
            Console.WriteLine("is a multichoice ");
            ((MultiChoice)question).addAnswer("a word");
            //((MultiChoice)question).Answers.Add("a word");
            // both of these add, but I added the custom version to check
        }
        else
        {
            Console.WriteLine("is NOT a multichoice");
        }

    }

I can't see what Ive missed to get these edited answers to be set to the data

Upvotes: 0

Views: 157

Answers (1)

dvandamme
dvandamme

Reputation: 26

So, after a couple of months now working with WPF c# (total dev time with WPF is 4 months) Ive finally fixed this issue by ripping the large bloaty xaml sections of these designs out into their own separate UserControl(s). This has enabled the UserControl(s) to be designed visually at design time, instead of with runtime only xaml as they where xaml data templates, and are now user controls as data templates. Previously, I didn't have the knowledge of how to stack all these controls together.

I'll leave this here as the actual answer to this very frustrating problem. mostly it came about because of my lack of vocabulary with C#wpf.

an observable collection doesn't trigger item modification on items unless those items are accessable by properties...

ObservableCollection<MyString> someStrings = new ObservableCollection<MyString>()

 class MyString
 {
     public string myString{get;set} 
 }

not

ObservableCollection<string> someStrings = new ObservableCollection<string>();

Upvotes: 0

Related Questions