Question

This problem might be solved easily but i'm having some serious issues with Binding a command from a viewModel to the xaml view file. As you might have guessed our application is based on the MVVM design pattern and currently has 2 windows (2 XAML files) and 2 viewModels (cs files).

The MainWindow.xaml is bound to MainViewModel where all commands are stored as ICommand objects. Everything works fine and all buttons work and reaches the commands they're bound to in the viewModel. One button then creates a new window called MultipleQuizWindow.xaml that are bound to a new ViewModel called MultipleQuizViewModel.cs but here is where the fun begins. The buttons are able to find the content that are used as labels and it looks like it can find the commands as well (no errors in the output menu when run) but when i click the button nothing happens? has tried almost everything and is starting to run out of ideas why it can find the ICommand without executing it. This is the code for the button that creates the new window:

(MainViewModel.cs)

        public void StartQuiz() {
        MultipleQuizWindow newWindow = new MultipleQuizWindow(this);
        newWindow.Show();
    }

Then the new Window is called and the specific viewModel gets the MainViewModel as an argument to the constructor.

MultipleQuizWindow.xaml.cs

    public partial class MultipleQuizWindow : Window {

    public MultipleQuizViewModel vmQuiz;

    public MultipleQuizWindow(MainViewModel mvm) {
        InitializeComponent();
        vmQuiz = new MultipleQuizViewModel(mvm);
        this.DataContext = vmQuiz;
    }
}

Then comes the xaml code for designing the window:

MultipleQuizWindow.xaml

<Window x:Class="VocApp.View.MultipleQuizWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:view="clr-namespace:VocApp.View"
    xmlns:viewmodel="clr-namespace:VocApp.ViewModel"
    Title="MultipleQuizWindow" Height="300" Width="300">
<Grid Name="Grid1">
    <Grid.RowDefinitions>
        <RowDefinition Height="56*" />
        <RowDefinition Height="43*" />
        <RowDefinition Height="43*" />
        <RowDefinition Height="43*" />
        <RowDefinition Height="43*" />
        <RowDefinition Height="42*" />
    </Grid.RowDefinitions>
    <Button Content="{Binding Ans1}" Name="Answer1" HorizontalAlignment="Left" Margin="108,10,0,0" Grid.Row="1" VerticalAlignment="Top" Width="75" Height="22" Command="{Binding Ans1Command}"/>
    <Button Command="{Binding Ans2Command}" Content="{Binding Ans2}" Name="Answer2" HorizontalAlignment="Left" Margin="108,10,0,0" Grid.Row="2" VerticalAlignment="Top" Width="75" Height="22"/>
    <Button Command="{Binding Ans3Command}" Content="{Binding Ans3}" Name="Answer3" HorizontalAlignment="Left" Margin="108,10,0,0" Grid.Row="3" VerticalAlignment="Top" Width="75" Height="22"/>
    <Button Command="{Binding Ans4Command}" Content="{Binding Ans4}" Name="Answer4" HorizontalAlignment="Left" Margin="108,13,0,0" Grid.Row="4" VerticalAlignment="Top" Width="75" Height="22"/>
    <Button Command="{Binding StartQuizCommand}" Content="{Binding Ans5}" Name="Answer5" HorizontalAlignment="Left" Margin="108,10,0,0" Grid.Row="5" VerticalAlignment="Top" Width="75" Height="22"/>
    <TextBlock Text="{Binding Text}" Name="QuestionBox" HorizontalAlignment="Left" Margin="32,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" RenderTransformOrigin="-1.48,-0.688" Height="36" Width="220"><Run Language="da-dk" Text=""/></TextBlock>
</Grid>

and finally comes the viewModel the windows is bound to (notice that it can find the content that the buttons are bound to but not the ICommands)

MultipleQuizViewModel

public class MultipleQuizViewModel : ViewModelBase {

    internal MainViewModel mvm;

    private string ans1;
    public string Ans1 {
        get {
            return ans1;
        }
        set {
            ans1 = value;
        }
    }
    private string ans2;
    public string Ans2 {
        get {
            return ans2;
        }
        set {
            ans2 = value;
        }
    }
    private string ans3;
    public string Ans3 {
        get {
            return ans3;
        }
        set {
            ans3 = value;
        }
    }
    private string ans4;
    public string Ans4 {
        get {
            return ans4;
        }
        set {
            ans4 = value;
        }
    }
    private string ans5;
    public string Ans5 {
        get {
            return ans5;
        }
        set {
            ans5 = value;
        }
    }
    private string text;
    public string Text {
        get {
            return text;
        }
        set {
            text = value;
        }
    }
    MultipleQuiz Quiz;
    public ICommand Ans1Command { get; private set; }
    public ICommand Ans2Command { get; private set; }
    public ICommand Ans3Command { get; private set; }
    public ICommand Ans4Command { get; private set; }
    public ICommand Ans5Command { get; private set; }

    public MultipleQuizViewModel(MainViewModel mvm) {
        this.mvm = mvm;
        this.Quiz = mvm.model.GenerateQuiz() as MultipleQuiz;
        string[] words = Quiz.AllAnswers;
        text = "Please translate the word " + Quiz.word.Wordstring;
        ans1 = words[0];
        ans2 = words[1];
        ans3 = words[2];
        ans4 = words[3];
        ans5 = words[4];
        Ans1Command = new RelayCommand(Answer1);
        Ans2Command = new RelayCommand(Answer2);
        Ans3Command = new RelayCommand(Answer3);
        Ans4Command = new RelayCommand(Answer4);
        Ans5Command = new RelayCommand(Answer5);
    }

    public void Answer1() {
        text = "please work";
        if (Quiz.ansIndex == 1) {
            text = "correct!";
        }
        else {
            text = "wrong!";
        }
    }

    public void Answer2() {
        if (Quiz.ansIndex == 2) {
            text = "correct!";
        }
        else {
            text = "wrong!";
        }
    }

    public void Answer3() {
        if (Quiz.ansIndex == 3) {
            text = "correct!";
        }
        else {
            text = "wrong!";
        }
    }

    public void Answer4() {
        if (Quiz.ansIndex == 4) {
            text = "correct!";
        }
        else {
            text = "wrong!";
        }
    }

    public void Answer5() {
        if (Quiz.ansIndex == 5) {
            text = "correct!";
        }
        else {
            text = "wrong!";
        }
    }
}

I know there is a ton of code there but I really hope someone might be able to tell me what went wrong. It is obvious that the commands is never executed still Visual Studio is able to find them through the bindings in xaml.

The project uses GalaSoft btw.

Thanks in advance to anyone who might give a tip that could lead me in the right direction :)

Was it helpful?

Solution

Why are you setting the private field "text" in your command method (public void Answer1)? You should set the public property Text (with a capital T) and have it implement INotifyPropertyChanged (OnPropertyChanged("Text");) in order to tell the view that the property has changed.

It's quite possible that the commands are working, but that you are not seeing the UI change because of this issues with Text that I mention. Try putting a breakpoint inside the Answer1() method and see if it gets hit when you click the button, if it does the problem is in the Text property.

Besides this, you have a typo in your quiz window here *Button Content="{Binding Ans1}"... should be "{Binding Ans1Command}"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top