【问题标题】:How to bind Start, End and Duration with Multibinding?如何使用多重绑定绑定开始、结束和持续时间?
【发布时间】:2016-01-21 11:23:35
【问题描述】:

我的 ViewModel 中有两个属性:

public double Start { get; set; }
public double Duration { get; set; }

我的视图中有三个文本框:

<TextBox Name="StartTextBox" Text="{Binding Start}" />
<TextBox Name="EndTextBox" />
<TextBox Name="DurationTextBox" Text="{Binding Duration} />

我想实现以下行为:

  • 当用户更改 Start- 或 EndTextBox 的内容时,DurationTextBox 应相应更新(Duration = End - Start)。
  • 当用户更改 DurationTextBox 时,应相应更新 EndTextBox(结束 = 开始 + 持续时间)。

我可以通过在后面的代码中监听 TextChanged 事件来实现这一点。不过,我更愿意通过 MultiBinding 来实现这一点。有可能吗?

我在尝试使用 MultiBinding 时遇到的问题:

  • 如果我将 MultiBinding 放在 DurationTextBox 上,我无法将它绑定到 Duration 属性。
  • 如果我将 MultiBinding 放在 EndTextBox 上并且用户更改了 StartTextBox,则会更新 EndTextBox 而不是 DurationTextBox。
  • 无论如何我都无法实现 ConvertBack 方法。

【问题讨论】:

  • 这样的行为应该在视图模型中实现。当例如Start 属性发生变化,视图模型也在内部更新其Duration 属性。这些属性当然也应该触发 PropertyChanged 事件。
  • @Clemens 这听起来很合理。这意味着,我添加了第三个属性 End 并将所有逻辑放在这些属性的设置器中,对吗?
  • 没错。并且视图模型类应该实现 INotifyPropertyChanged 接口。

标签: c# wpf multibinding imultivalueconverter


【解决方案1】:

我认为打击代码更容易实现您想要的行为:

XAML:

<TextBox Name="StartTextBox" Text="{Binding Start}" />
<TextBox Name="EndTextBox" Text="{Binding End}" />
<TextBox Name="DurationTextBox" Text="{Binding Duration}" />

视图模型:

    private double _start;
    private double _duration;
    private double _end;
    public double Start
    {
        get
        {
            return _start;
        }
        set
        {
            if (_start != value)
            {
                _start = value;
                Duration = _end - _start;
                OnPropertyChanged("Start");
            }
        }
    }
    public double Duration
    {
        get
        {
            return _duration;
        }
        set
        {
            if (_duration != value)
            {
                _duration = value;
                End = _duration + _start;
                OnPropertyChanged("Duration");
            }
        }
    }
    public double End
    {
        get
        {
            return _end;
        }
        set
        {
            if (_end != value)
            {
                _end = value;
                Duration = _end - _start;
                OnPropertyChanged("End");
            }
        }
    }

ViewModel 中的 OnPropertyChanged 实现了 INotifyPropertyChanged 接口,如下所示:

public class ViewModelBase:INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

【讨论】:

  • 虽然我同意这可能是继 MVVM 之后最好的解决方案,但这并不是对 MultiBinding 是否可能的问题的真正答案。无论如何,谢谢,看起来不错,我可能最终会使用它。
  • @TimPohlmann 这个答案是:根本没有。 MultiBinding 用于将多个源属性(例如来自视图模型)绑定到视图中的单个目标属性,即反过来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-24
  • 1970-01-01
  • 2010-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
相关资源
最近更新 更多