0

I'm Trying to make a simple quiz program in Windows 8 using the MVVM design pattern. I tried to Use PRISM and MVVMlite but I'm a newb and simply don't have enough knowledge of data and control binding to understand how to use it correctly. I think I have the majority of it working but I a few major problems. 1. my GUI doesn't update properly. 2. I'm receiving several errors. 3. Fixing one part of my code breaks another part. 4. Can't figure out how to get "sender" information from command in XAML.

here is my code so far:

xml data:

<root>
  <Object>
    <Question>What do you do for work</Question>
    <Answer>Wrestle giant tentical monsters</Answer>
    <Choices>Battle robots</Choices>
    <Choices>Glorious ruler of North Korea</Choices>
    <Choices>Wrestle Giant Tentical Monsters</Choices>
    <Choices>Defender of all that is good</Choices>
  </Object>

  <Object>
    <Question>What do you drive</Question>
    <Answer>Moped</Answer>
    <Choices>Helicopter</Choices>
    <Choices>Pegasus</Choices>
    <Choices>Rocketship</Choices>
    <Choices>Moped</Choices>
  </Object>
</root>

Model:

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.ComponentModel;
 using System.Xml.Linq;
 using System.Windows.Input;

namespace Quiz
    {
    class QuizModel : INotifyPropertyChanged
    {
        private string _question;
        public string Question
        {
            get { return _question; }
            set
            {
                _question = value;
                OnPropertyChanged("Question");
            }
        }

        private string _answer;
        public string Answer
        {
            get { return _answer; }
            set
        {
            _answer = value;
            OnPropertyChanged("Answer");
        }
    }

    private List<string> _choices;
    public List<string> Choices
    {
        get { return _choices; }
        set
        {
            _choices = value;
            OnPropertyChanged("Choices");
        }
    }

    public QuizModel(string quesiton, string answer, List<string> choices)
    {
        Question = quesiton;
        Answer = answer;
        Choices = choices;
    }

    public static List<QuizModel> Query(string datasource)
    {
        XElement quizdata = XElement.Load(datasource);
        List<QuizModel> query = (from d in quizdata.Descendants("Object")
                                 select new QuizModel(
                                             (string)d.Element("Question"),
                                             (string)d.Element("Answer"),
                                             d.Elements("Choices").Select(a => a.Value).ToList()
                                             )).ToList();
        return query;
    }

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

View Model:

class QuizViewModel
{
    public static List<QuizModel> QuizList { get; set; }
    public static QuizModel Quiz { get; set; }
    public static int Indexer { get; set; }
    public ICommand myCommand { get; set; }

    //Initiallizes view model
    public QuizViewModel()
    {
        Indexer = 0;
        QuizList = QuizModel.Query("Quiz.xml");
        Quiz = QuizList[Indexer];
        myCommand = new ActionCommand(Evaluate);
    }

    //Increments to next question
    private void Evaluate()
    {
        Indexer++;
        Quiz = QuizList[Indexer];
    }
}

iCommand:

public class ActionCommand : ICommand
{
    private readonly Action _action;
    public ActionCommand(Action action)
    {
        _action = action;
    }

    public void Execute(object parameter)
    {
        _action();
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged; //ERROR event Never Used
}

}

View:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="3*"/>
    </Grid.RowDefinitions>
    <TextBlock FontSize="50" Text="{Binding Quiz.Question}">
        <TextBlock.DataContext>
            <local:QuizViewModel/>  <!--Can't find Quiz.xml-->
        </TextBlock.DataContext>
    </TextBlock>

    <ListView Grid.Row="1" FontSize="30" ItemsSource="{Binding Quiz.Choices}">
        <ListView.DataContext>
            <local:QuizViewModel/> <!--Can't find Quiz.xml-->
        </ListView.DataContext>

        <ListView.ItemTemplate>
            <DataTemplate>
                <Button Content="{Binding Mode=OneWay}" Command="{Binding myCommand}">
                    <Button.DataContext>
                        <local:QuizViewModel/>
                    </Button.DataContext>
                </Button>
            </DataTemplate>
        </ListView.ItemTemplate>
     </ListView>
</Grid>

I have 3 current errors 2 of which are the same first error refers to in the XAMLs datacontext:

Error 1 (x2)
Could not find file 'C:\Users\Me\AppData\Local\Microsoft\VisualStudio\11.0\Designer\ShadowCache\cv0te54x.fpv\5ncl4yxi.hui\Quiz.xml'.

Error 2 Cannot create instance of type 'Quiz.QuizViewModel'

This seems to effect my "Choices" not populating, I can fix this by removing the data context, but then I can't bind "myCommand"

Third problem is how do I the Sender information from the command input so I can evaluate if it is right or wrong?

evilsushi
  • 115
  • 1
  • 8

1 Answers1

0

Take a look at the error #1, your code can't find the Quiz.xml file and it is looking for it at the location in the error description. It seems it's looking at the wrong location, so you might have to specify a more concrete path for it. This question may help, if you have the xml file in the resources. Because this is done in the Quiz.QuizViewModel constructor, the creating of the instance fails and produces error #2.

As for the third part, you can pass the command an arbitrary parameter. In this case it might be the choice or its position. Something like this

Community
  • 1
  • 1
Honza Brestan
  • 10,637
  • 2
  • 32
  • 43
  • Well it populates initially, it just won't update to the next selection. I tried to make the path more concrete but it threw up numerous errors when I did. I have it set as content right now, I tried embedded resource but that didn't work. I will try your idea for the third problem. Thanks – evilsushi Jun 01 '13 at 10:16
  • Any advice on how I can make my path more concrete for "Quiz.xml". It currently is in source directory so I don't what I can do to make it any more concrete. – evilsushi Jun 01 '13 at 11:53