首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RelayCommand Params &绑定

RelayCommand Params &绑定
EN

Stack Overflow用户
提问于 2012-08-15 15:15:56
回答 2查看 2.4K关注 0票数 0

视图:

使用WPF(MVVM)玩基本计算器。对于第一个num,我有一个TextBox,对于第二个num有一个TextBox,对于结果有一个TextBlock,有一个按钮来执行AddCommand并返回结果。什么是正确的XAML语法将这些控件绑定到正确的数据。

模型:

代码语言:javascript
复制
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;
    }
}

ViewModel:

代码语言:javascript
复制
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的请求编辑新版本的代码

模型:

代码语言:javascript
复制
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;
        }
    }

ViewModel:

代码语言:javascript
复制
 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:

代码语言:javascript
复制
<TextBox Text="{Binding LeftNumber}" />
<TextBox Text="{Binding RightNumber}" />
<TextBox Text="{Binding Result}" />
<Button Content="Add" Command="{Binding AddCommand}" />

视图代码背后:

代码语言:javascript
复制
public partial class CalcUserControl : UserControl
{
    CalcViewModel vm;

    public CalcUserControl()
    {
        InitializeComponent();
        vm = new CalcViewModel();
        this.DataContext = vm;
    }
}

我尝试了所有的绑定模式,但没有任何结果。我在这里还有一个问题,在这种情况下,默认的绑定模式是什么?

我甚至认为这与计算的数据类型有关,所以我从double到int,但仍然不起作用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-15 15:27:22

好吧,让我们看看能做什么。

1)模型。模型不需要任何花哨的东西。我会保持简单,让它只返回值,而不是使用NotifyPropertyChanged。毕竟,这是个模特。

代码语言:javascript
复制
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!因此,您需要3 DPs (左加载项,右加载项,结果)在您的VM。

3)当命令到达时,只需从VM获取加载项,请模型执行操作,检索结果并将其分配给VM的结果DP。(现在,您的模型操作是快速的,所以您不需要以异步的方式完成它。但也许在将来.)

4)视图。您需要使用窗口/UserControl来绑定到VM的属性。它将是一件简单的事情,如:

代码语言:javascript
复制
<TextBox Text="{Binding LeftAddend}"/>
<TextBox Text="{Binding RightAddend}"/>
<TextBox Text="{Binding Result}"/>
<Button Command="{Binding AddCommand}">Add</Button>

(不要忘记将DataContext设置为正确的。)

编辑:

VM类必须是一个依赖对象!属性应该定义为依赖项属性。就像这样:

代码语言:javascript
复制
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

代码语言:javascript
复制
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版本也是如此:

代码语言:javascript
复制
    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");
        }
    }

等。

票数 0
EN

Stack Overflow用户

发布于 2012-08-16 15:16:15

谢谢大家,特别是弗拉德。只是一个小小的错误,y已经在class CalcViewModel : DependencyObject上声明了属性class CalcViewModel : DependencyObject两次。

它现在运作良好:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11972092

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档