WPF-MVVMパターンを初めて使用しています。私は2つの数字の加算を実行する小さなアプリケーションを書いています。 2つの数字は、ボタンがクリックされたときに追加が行われる間にユーザーによって入力されます。WPF MVVMパターン - コントロールのバインディングが機能しない
問題はResult
が3番目のテキストボックスにバインドしていないことです。続き
は私のコード(あなたは追加の問題を発見した場合MVVMに新しいもの、私に知らせてください)です。
のAppクラス - スタートアップ
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
MVVM_Math_Calc.Views.Calculator calc = new Views.Calculator();
MVVM_Math_Calc.ViewModels.CalculatorViewModel context = new ViewModels.CalculatorViewModel();
calc.DataContext = context;
calc.Show();
}
}
ビュー
<Window x:Class="MVVM_Math_Calc.Views.CalculatorWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Calculator" Height="200" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Label Content="Number 1" Grid.Column="0" Grid.Row="0" Foreground="Blue" />
<Label Content="Number 1" Grid.Column="1" Grid.Row="0" Foreground="Blue" />
<Label Content="Result" Grid.Column="2" Grid.Row="0" Foreground="Blue" />
<TextBox Name="Num1" Text="{Binding Number1}" Grid.Column="0" Grid.Row="1" BorderBrush="Gray" />
<TextBox Name="Num2" Text="{Binding Number2}" Grid.Column="1" Grid.Row="1" BorderBrush="Gray" />
<TextBox Name="Answer" Text="{Binding Result}" Grid.Column="2" Grid.Row="1" BorderBrush="Gray" />
<Button Content="Addition" Command="{Binding Path=AddNumbersCommand}" Grid.Column="0" Grid.Row="2" />
</Grid>
</Window>
CalculatorViewModel
public class CalculatorViewModel : ViewModelBase
{
private CalculatorModel calculatorModel;
private ICommand additionCommand;
public CalculatorViewModel()
{
this.CalculatorModel = new CalculatorModel (20, 10);
}
public CalculatorModel CalculatorModel
{
get
{ return calculatorModel; }
set
{ calculatorModel = value; }
}
public int Result
{
get { return this.CalculatorModel.Result; }
set { this.CalculatorModel.Result = value; }
}
public int Number1
{
get { return this.CalculatorModel.Number1; }
set { this.CalculatorModel.Number1 = value; }
}
public int Number2
{
get { return this.CalculatorModel.Number2; }
set { this.CalculatorModel.Number2 = value; }
}
public ICommand AddNumbersCommand
{
get
{
if (additionCommand == null)
{
additionCommand = new DelegateCommand(param => AddNumbers());
}
return additionCommand;
}
}
public void AddNumbers()
{
Debug.WriteLine ("Addition");
this.CalculatorModel.Result = this.CalculatorModel.Number1 + this.CalculatorModel.Number2;
this.Result = this.calculatorModel.Result;
}
}
CalculatorModel
public class CalculatorModel : ViewModelBase
{
private int num1;
private int num2;
private int result;
public CalculatorModel()
{}
public CalculatorModel (int n1, int n2)
{
this.Number1 = n1;
this.Number2 = n2;
this.Result = 0;
}
public int Number1
{
get
{ return num1; }
set
{
if (value != num1)
{
num1 = value;
OnPropertyChanged("Number1");
}
}
}
public int Number2
{
get
{ return num2; }
set
{
if (value != num2)
{
num2 = value;
OnPropertyChanged ("Number2");
}
}
}
public int Result
{
get
{ return result; }
set
{
if (value != result)
{
result = value;
OnPropertyChanged ("Result");
}
}
}
}
ViewModelBase
public class ViewModelBase : INotifyPropertyChanged
{
// event handler
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged (string propertyName)
{
this.VerifyPropertyName (propertyName);
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler (this, new PropertyChangedEventArgs(propertyName));
}
}
public virtual void VerifyPropertyName(string propertyName)
{
// Verify that the property name matches a real,
// public, instance property on this object.
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
{
string msg = "Invalid property name: " + propertyName;
throw new Exception ("Error");
}
}
}
DelegateCommand
public class DelegateCommand : ICommand
{
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
public DelegateCommand (Action<object> execute) : this (execute, null)
{}
/// <param name="canExecute">The execution status logic.</param>
public DelegateCommand (Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
[DebuggerStepThrough]
public bool CanExecute(object parameters)
{
return _canExecute == null ? true : _canExecute(parameters);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameters)
{
Debug.WriteLine("Execute");
_execute (parameters);
}
}
viewmodelでこれらのプロパティを追加のプロパティとして公開する代わりに、CalculatorModel.Number1、CalculatorModel.Number2、CalculatorModel.Resultにバインドしてみてください。また、viewmodelのCalculatorModelプロパティのPropertyChangedイベントを発生させます。 –