我有一份问卷调查申请表,我希望一次一个地显示对象(问题+我的案例中的答案)。这意味着我希望用户显示第一个问题,回答它,然后单击按钮并获得第二个问题(在同一窗口中),单击另一个按钮/或相同的按钮并获得第三个问题,依此类推。目前,我很难通过仅使用XAML将第二个问题绑定到我的按钮。是否可以在不使用代码的情况下执行此操作?如果是这样,请给我一个想法。谢谢你的期待。
这是我的ViewModel:
namespace TestAppMVVM.ViewModel
{
public class TestViewModel
{
public ObservableCollection<Test> BeginnerTests
{
get;
set;
}
public Test CurrentQuestion
{
get;
set;
}
public Test NextQuestion
{
get;
set;
}
public Test CurrentAnswer
{
get;
set;
}
public Test NextAnswer
{
get;
set;
}
public void LoadBeginner()
{
ObservableCollection<Test> tests = new ObservableCollection<Test>();
tests.Add(new Test { Index = 1, Question = "1.What is the capital of England ?", FirstAnswer = "Paris", SecondAnswer = "London", ThirdAnswer = "Berlin" });
tests.Add(new Test { Index = 2, Question = "2.What is the capital of France ?", FirstAnswer = "Paris", SecondAnswer = "London", ThirdAnswer = "Berlin" });
tests.Add(new Test { Index = 3, Question = "3.What is the capital of Germany ?", FirstAnswer = "Paris", SecondAnswer = "London", ThirdAnswer = "Berlin" });
BeginnerTests = tests;
CurrentQuestion = BeginnerTests[0];
CurrentAnswer = BeginnerTests[0];
NextQuestion = BeginnerTests[1];
NextAnswer = BeginnerTests[1];
}
}
}
在这里我粘贴了视图:
<Grid Background="Yellow">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height ="20"/>
<RowDefinition Height ="100"/>
<RowDefinition Height ="auto"/>
<RowDefinition Height ="auto"/>
<RowDefinition Height ="30"/>
<RowDefinition Height ="*"/>
<RowDefinition Height ="20"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Grid.Row="1" FontSize="25" Grid.ColumnSpan="3" Text="{Binding CurrentQuestion.Question}"/>
<StackPanel Orientation="Horizontal" Grid.Column="2" Grid.Row="3" Grid.ColumnSpan="5">
<RadioButton FontWeight="Bold" Content="{Binding CurrentAnswer.FirstAnswer}"/>
<RadioButton FontWeight="Bold" Margin="10 0 0 0" Content="{Binding CurrentAnswer.SecondAnswer}"/>
<RadioButton FontWeight="Bold" Margin="10 0 0 0" Content="{Binding CurrentAnswer.ThirdAnswer}"/>
</StackPanel>
<Button FontWeight="Bold" x:Name="nextButton" Content="Next Question" Grid.Column="2" Grid.Row="5"/>
答案 0 :(得分:0)
有一种方法是在ViewModel中公开名为MoveNext
的ICommandICommand界面在https://msdn.microsoft.com/en-us/library/system.windows.input.icommand(v=vs.110).aspx
class MoveNextCommand : ICommand
{
...... <Your implementation>
}
public class TestViewModel
{
...
private ICommand _moveNextCmd;
public ICommand MoveNextCmd
{
get { return _moveNextCmd ?? (_moveNextCmd = new MoveNextCommand()); }
}
...
}
在XAML中
<Button FontWeight="Bold" x:Name="nextButton" Content="Next Question" Grid.Column="2" Grid.Row="5" Command={Binding MoveNextCmd} />
命令的逻辑只是改变ViewModel的CurrentQuestion。
重要的是,您的ViewModel必须实现INotifyPropertyChanged接口,并且属性的setter必须调用OnPropertyChanged,否则在更改属性值时不会看到任何更新。
答案 1 :(得分:0)
如果你想避免使用后面的代码并为此实现MVVM,你需要实现ICommand。
将其放入 ViewModel :
public ICommand ExecuteCommand
{
get
{
if (_command == null)
{
_command = new RelayCommand(param => this.NextQuestion());
}
return _command;
}
}
public void NextQuestion()
{
//Do Stuff Here
}
将此按钮添加到 XAML :
,将其绑定到该按钮Command="{Binding Path=ExecuteCommand}"
最后,在项目中添加 RelayCommand 类:
public class RelayCommand : ICommand
{
readonly Action<object> _ActionToExecute;
readonly Predicate<object> _ActionCanExecute;
public RelayCommand(Action<object> inActionToExecute): this(inActionToExecute, null)
{
}
public RelayCommand(Action<object> inActionToExecute, Predicate<object> inActionCanExecute)
{
if (inActionToExecute == null)
throw new ArgumentNullException("execute");
_ActionToExecute = inActionToExecute;
_ActionCanExecute = inActionCanExecute;
}
public bool CanExecute(object parameter)
{
return _ActionCanExecute == null ? true : _ActionCanExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_ActionToExecute(parameter);
}
}