查看:
使用WPF(MVVM)播放基本计算器。 我有1个TextBox用于第一个num,1个TextBox用于第二个num,1个TextBlock用于结果,1个Button用于执行AddCommand并返回结果。 什么是将这些控件绑定到正确数据的正确XAML语法。
型号:
public class Operation : INotifyPropertyChanged
{
private double _result;
public Operation()
{
_result = 0;
}
public double Result
{
get { return _result; }
set
{
if (value != _result)
{
_result = value;
RaisePropertyChanged("Result");
}
}
}
public double DoAdd(double first, double second)
{
_result = first + second;
return _result;
}
}
视图模型:
public class CalcViewModel
{
private Operation _operation;
public RelayCommand AddCommand { get; set; }
public CalcViewModel()
{
_operation = new Operation();
// This is not correct, how to define the AddCommand here so it takes two params
// The first and second nums to work with.
AddCommand = new RelayCommand(first, second => ExecuteAddCommand(first, second));
}
private void ExecuteAddCommand(double first, double second)
{
// How to bind this returned double to the TextBlock in View
_oepration.DoAdd(first, second);
}
}
根据Vlad的要求编辑新版代码
型号:
public class Operation
{
private double _result;
public Operation()
{
_result = 0;
}
public double Result
{
get { return _result; }
}
public void PerformAdd(double leftNum, double rightNum)
{
_result = leftNum + rightNum;
}
}
视图模型:
public class CalcViewModel
{
private Operation _operation;
public double LeftNumber { get; set; }
public double RightNumber { get; set; }
public double Result { get; set; }
public RelayCommand AddCommand { get; set; }
public CalcViewModel()
{
AddCommand = new RelayCommand(a => ExecuteAddCommand());
_operation = new Operation();
}
private void ExecuteAddCommand()
{
_operation.PerformAdd(LeftNumber, RightNumber);
Result = _operation.Result;
}
查看XAML:
<TextBox Text="{Binding LeftNumber}" />
<TextBox Text="{Binding RightNumber}" />
<TextBox Text="{Binding Result}" />
<Button Content="Add" Command="{Binding AddCommand}" />
查看代码背后:
public partial class CalcUserControl : UserControl
{
CalcViewModel vm;
public CalcUserControl()
{
InitializeComponent();
vm = new CalcViewModel();
this.DataContext = vm;
}
}
我尝试了所有绑定模式而没有任何结果。我在这里有一个额外的问题,在这种情况下什么是默认的绑定模式?
我甚至认为它与计算的数据类型有关,所以我从double变为int,但仍无法正常工作。
答案 0 :(得分:0)
好吧,让我们看看可以做些什么。
1)模型。该模型不需要任何花哨的东西。我会保持简单,让它只返回值,而不是使用NotifyPropertyChanged
。毕竟,这是一个模型。
public class BinaryOperation
{
double _l, _r, _result = 0.0;
public Operation(double l, double r)
{
_l = l; _r = r;
}
public double Result
{
get { return _result; }
}
public PerformAdd()
{
_result = _l + _r;
}
}
2)ViewModel。在这里,您的RelayCommand
并不需要任何参数。但是您需要在VM中存储操作数的值,以便您的视图可以绑定到它们,而不是在命令中发送它们。请记住,业务逻辑不属于视图,视图只是盲目地绑定到VM!因此,您需要在VM中使用3个DP(左加数,右加数,结果)。
3)当命令到达时,您只需从VM获取加数,请模型执行操作,检索结果并将其分配给VM的结果DP。 (现在,您的模型操作速度很快,因此您不需要以异步方式执行此操作。但可能在将来......)
4)查看。您需要将Window / UserControl绑定到VM的属性。 它将变得如此简单:
<TextBox Text="{Binding LeftAddend}"/>
<TextBox Text="{Binding RightAddend}"/>
<TextBox Text="{Binding Result}"/>
<Button Command="{Binding AddCommand}">Add</Button>
(不要忘记将DataContext
设置为正确。)
编辑:
VM类必须是依赖对象!并且属性应该定义为依赖属性。像这样:
public class CalcViewModel : DependencyObject
{
private Operation _operation;
public double LeftNumber
{
get { return (double)GetValue(LeftNumberProperty); }
set { SetValue(LeftNumberProperty, value); }
}
public static readonly DependencyProperty LeftNumberProperty =
DependencyProperty.Register("LeftNumber", typeof(double), typeof(CalcViewModel));
public double RightNumber
{
get { return (double)GetValue(RightNumberProperty); }
set { SetValue(RightNumberProperty, value); }
}
public static readonly DependencyProperty RightNumberProperty =
DependencyProperty.Register("RightNumber", typeof(double), typeof(CalcViewModel));
public double Result
{
get { return (double)GetValue(ResultProperty); }
set { SetValue(ResultProperty, value); }
}
public static readonly DependencyProperty ResultProperty =
DependencyProperty.Register("Result", typeof(double), typeof(CalcViewModel));
public RelayCommand AddCommand { get; set; }
public CalcViewModel()
{
AddCommand = new RelayCommand(a => ExecuteAddCommand());
_operation = new Operation();
}
private void ExecuteAddCommand()
{
_operation.PerformAdd(LeftNumber, RightNumber);
Result = _operation.Result;
}
}
或者,如果您想使用INotifyPropertyChanged
,并且您正在使用.NET 4.5
public class CalcViewModel : INotifyPropertyChanged
{
private Operation _operation;
public event PropertyChangedEventHandler PropertyChanged;
void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
double _leftNumber;
public double LeftNumber
{
get { return _leftNumber; }
set
{
if (value == _leftNumber) return;
_leftNumber = value;
NotifyPropertyChanged();
}
}
double _rightNumber;
public double RightNumber
{
get { return _rightNumber; }
set
{
if (value == _rightNumber) return;
_rightNumber = value;
NotifyPropertyChanged();
}
}
double _result;
public double Result
{
get { return _result; }
set
{
if (value == _result) return;
_result = value;
NotifyPropertyChanged();
}
}
public RelayCommand AddCommand { get; set; }
public CalcViewModel()
{
AddCommand = new RelayCommand(a => ExecuteAddCommand());
_operation = new Operation();
}
private void ExecuteAddCommand()
{
_operation.PerformAdd(LeftNumber, RightNumber);
Result = _operation.Result;
}
}
与旧的.NET版本相同:
void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
double _leftNumber;
public double LeftNumber
{
get { return _leftNumber; }
set
{
if (value == _leftNumber) return;
_leftNumber = value;
NotifyPropertyChanged("LeftNumber");
}
}
等
答案 1 :(得分:0)
谢谢大家,特别是@Vlad。只是一个小小的错误,你已经在Result
两次声明属性class CalcViewModel : DependencyObject
。
现在工作正常:)