1

I have two properties in my ViewModel:

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

I have three textboxes in my View:

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

I want to achieve the following behavior:

  • When the user changes the content of the Start- or the EndTextBox, the DurationTextBox should be updated accordingly (Duration = End - Start).
  • When the user changes the DurationTextBox, the EndTextBox should be updated accordingly (End = Start + Duration).

I can achieve this by listening to the TextChanged events in code behind. I would prefer to achieve this via MultiBinding, though. Is it possible?

The problems I encounter, when I try to use MultiBinding:

  • If I put the MultiBinding on the DurationTextBox I cannot bind it to the Duration property.
  • If I put the MultiBinding on the EndTextBox and the user changes the StartTextBox, the EndTextBox gets updated instead of the DurationTextBox.
  • In any case I'm not able to implement the ConvertBack method.
Tim Pohlmann
  • 4,140
  • 3
  • 32
  • 61
  • 1
    Such a behaviour should be implemented in the view model. When e.g. the `Start` property changes, the view model also updates its `Duration` property internally. The properties should of course also fire PropertyChanged events. – Clemens Oct 22 '15 at 08:49
  • @Clemens That sounds reasonable. This means, I add a third property End and put all logic in the setters of those properties, right? – Tim Pohlmann Oct 22 '15 at 08:50
  • 1
    Exactly. And the view model class should implement the INotifyPropertyChanged interface. – Clemens Oct 22 '15 at 08:53

1 Answers1

1

I think blow codes are much easier to achieve the behavior which you want:

XAML:

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

ViewModel:

    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");
            }
        }
    }

The OnPropertyChanged in ViewModel implements the INotifyPropertyChanged interface like this:

public class ViewModelBase:INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
Prince
  • 199
  • 1
  • 3
  • 14
  • While I agree that this is probably the nicest solution following MVVM, this is not really an answer to the question if it is possible with MultiBinding. Thanks anyway, looks pretty good, I might end up using it. – Tim Pohlmann Oct 22 '15 at 08:56
  • @TimPohlmann This answer is: not at all. MultiBinding is meant for binding multiple source properties (e.g. from a view model) to a single target property in the view, i.e. the other way round. – Clemens Oct 22 '15 at 09:42