Elad Yehuda
Member
- Joined
- Jul 3, 2023
- Messages
- 10
- Programming Experience
- 3-5
I have a problem, that I am trying to access an object that is itself a list
of objects.
The structure is like this, I have some class called Client and that class has a property Matched_ which itself contains a list of questionnaires, each questionnaire has a list of questions.
Because of the requirements of the project, I split the Question class and decided to create a basic entity BaseQuestionEntity that will contain only one property of Id, and the Question class inherits from it and adds a property that saves the content of the question as a QuestionText string. Now I also have another QuestionAnswers class that inherits from BaseQuestionEntity and should keep a list of "answers" not as a string but only the Id of each answer.
At the beginning of the program I read an xml file which converts it into a list of Questionnaires according to the list of QuestionAnswers which saves me the answers for each question according to each questionnaire! The content is saved in a list property called AnswersQuestionnaires that I initially specified in the Matched_ object that exists in every client object (sounds a bit complicated but the full code continues), during the program in a certain window I transfer a client, in the exact same window to the constructor, in the xaml itself I make Bindings to the properties of that client for any fields, in addition I make a special Binding of the AnswersQuestionnaires property in twoway mode, the same UserControl
I have defined special functions of dependency properties for the binding, and when the function is activated that should receive the QuestionAnswers property as it is and I am trying to make a conversion from one element of the list of List<BaseQuestionEntity> to
QuestionAnswers I just get null! And I don't understand why this is happening?
In the window itself I do see that for a certain client the list is in the form of QuestionAnswers and not and I can access every element of it!
Here is the full code:
of objects.
The structure is like this, I have some class called Client and that class has a property Matched_ which itself contains a list of questionnaires, each questionnaire has a list of questions.
Because of the requirements of the project, I split the Question class and decided to create a basic entity BaseQuestionEntity that will contain only one property of Id, and the Question class inherits from it and adds a property that saves the content of the question as a QuestionText string. Now I also have another QuestionAnswers class that inherits from BaseQuestionEntity and should keep a list of "answers" not as a string but only the Id of each answer.
At the beginning of the program I read an xml file which converts it into a list of Questionnaires according to the list of QuestionAnswers which saves me the answers for each question according to each questionnaire! The content is saved in a list property called AnswersQuestionnaires that I initially specified in the Matched_ object that exists in every client object (sounds a bit complicated but the full code continues), during the program in a certain window I transfer a client, in the exact same window to the constructor, in the xaml itself I make Bindings to the properties of that client for any fields, in addition I make a special Binding of the AnswersQuestionnaires property in twoway mode, the same UserControl
I have defined special functions of dependency properties for the binding, and when the function is activated that should receive the QuestionAnswers property as it is and I am trying to make a conversion from one element of the list of List<BaseQuestionEntity> to
QuestionAnswers I just get null! And I don't understand why this is happening?
In the window itself I do see that for a certain client the list is in the form of QuestionAnswers and not and I can access every element of it!
Here is the full code:
C#:
// all class
[AddINotifyPropertyChangedInterface]
public class Questionnaire
{
public int Id { get; set; }
public List<BaseQuestionEntity> Questions { get; set; }
}
public class BaseQuestionEntity
{
public int Id { set; get; }
}
public class Question : BaseQuestionEntity
{
public string QuestionText { get; set; }
}
public class QuestionAnswers: BaseQuestionEntity
{
public HashSet<int> IdAnswers { get; set; }
}
[AddINotifyPropertyChangedInterface]
[Serializable]
public class Client
{
private DateTime? selectedDateOfBirth;
private string hebrewDateOfBirth;
public string Id { get; set; }
//.....
public Matched Matched { get; set; }
}
[AddINotifyPropertyChangedInterface]
public class Matched
{
public List<Questionnaire> AnswersQuestionnaires { get; set; }
}
//....
//...
public static async Task<Client> GetClient(string clientInfoFilePath)
{
// DeserializeFromXml is read file xml of Client
Client client = DeserializeFromXml<Client>(clientInfoFilePath);
string folder = $"FolderClients/{client.PathFolder}";
string matchedFilePath = Path.Combine(folder, "AnswerClientQuestionnaires.xml");
if (client.Matched_ != null && File.Exists(matchedFilePath))
{
client.Matched_.AnswersQuestionnaires = await Task.Run(() => ReadClientAnswerQuestionnaireAsync(matchedFilePath));
}
}
// function to read file xml
public static async Task<List<Questionnaire>> ReadClientAnswerQuestionnaireAsync(string filePath)
{
try
{
if (!File.Exists(filePath))
{
return null;
}
XDocument xmlDoc = await Task.Run(() => XDocument.Load(filePath));
var questionnaires = xmlDoc.Descendants("Questionnaire").Select(q =>
{
var questionnaireId = int.Parse(q.Attribute("Id").Value);
var questions = q.Descendants("Question").Select(qs =>
{
var questionId = int.Parse(qs.Attribute("Id").Value);
var answers = new QuestionAnswers
{
Id = questionId,
IdAnswers = new HashSet<int>(qs.Descendants("AnswerImage").Select(a => int.Parse(a.Value)))
};
return answers;
}).Cast<BaseQuestionEntity>().ToList();
return new Questionnaire { Id = questionnaireId, Questions = questions };
}).ToList();
return questionnaires;
}
catch (Exception ex)
{
Console.WriteLine($"Error occurred while reading XML file: {ex.Message}");
return null;
}
}
// Window
public partial class CreatNewClient : CustomBaseWindow
{
private Client cl, oldClient;
public CreatNewClient()
{
InitializeComponent();
}
public CreatNewClient(Client oldClient)
{
//...
//...
// here te get list QuestionAnswers properly
var listQuestionAnswers = oldClient.Matched_.AnswersQuestionnaires[0].Questions.OfType<QuestionAnswers>().ToList();
InitializeComponent();
}
//...
//..
}
//xaml of CreatNewClient
<custom:CustomBaseWindow x:Class="PMV.Views.CreatNewClient"
xmlns:uc="clr-namespace:PMV.Components"
//....
>
<Grid>
<!--...-->
<uc:QuestionnairePanel x:Name="ucQuestionnairePanel" ParentWindow="{Binding RelativeSource={RelativeSource AncestorType=Window}}" ClientSerialNumber="{Binding SerialNumber, Mode=TwoWay}" ClientAnswers="{Binding Matched_.AnswersQuestionnaires, Mode=TwoWay}" GenderClient="{Binding Gender, Mode=TwoWay}"/>
</Grid>
</custom:CustomBaseWindow>
// UserControl QuestionnairePanel
public partial class QuestionnairePanel : UserControl
{
List<Questionnaire> questionnairesCurrent;
int indexQuestionnaire, indexQustion;
List<Questionnaire> clientAnswers;
//...
public static readonly DependencyProperty ClientSerialNumberProperty = DependencyProperty.Register("ClientSerialNumber", typeof(string),
typeof(QuestionnairePanel), new FrameworkPropertyMetadata(null, ClientSerialNumberPropertyChanged));
public static readonly DependencyProperty GenderClientProperty = DependencyProperty.Register("GenderClient", typeof(bool?),
typeof(QuestionnairePanel), new FrameworkPropertyMetadata(null, GenderClientPropertyChanged));
public static readonly DependencyProperty ClientAnswersProperty = DependencyProperty.Register("ClientAnswers", typeof(List<Questionnaire>),
typeof(QuestionnairePanel), new FrameworkPropertyMetadata(null, ClientAnswersPropertyChanged));
public static readonly DependencyProperty ParentWindowProperty = DependencyProperty.Register("ParentWindow", typeof(Window), typeof(QuestionnairePanel), new PropertyMetadata(null));
private static void ClientSerialNumberPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is QuestionnairePanel qustionPanel)
{
qustionPanel.ClientSerialNumber = (string)e.NewValue;
}
}
private static void ClientAnswersPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is QuestionnairePanel qustionPanel)
{
var temp = (List<Questionnaire>)e.NewValue;
if (temp != null && temp != qustionPanel.clientAnswers)
{
qustionPanel.clientAnswers = temp;
// here lisQuestionAnswers is list empty after casting!
var lisQuestionAnswers = temp[0].Questions.OfType<QuestionAnswers>().ToList();
}
qustionPanel.buMatch.Visibility = Visibility.Visible;
}
}
public Window ParentWindow
{
get { return (Window)GetValue(ParentWindowProperty); }
set { SetValue(ParentWindowProperty, value); }
}
public string ClientSerialNumber
{
get { return (string)GetValue(ClientSerialNumberProperty); }
set { SetValue(ClientSerialNumberProperty, value); }
}
public bool? GenderClient
{
get { return (bool?)GetValue(GenderClientProperty); }
set { SetValue(GenderClientProperty, value); }
}
public List<Questionnaire> ClientAnswers
{
get { return (List<Questionnaire>)GetValue(ClientAnswersProperty); }
set { SetValue(ClientAnswersProperty, value); }
}
// The rest of the code
// ...
}