views:

27

answers:

1

Maybe I am not quite grasping multibindings.

I have a property on my viewmodel called OfficeDisplayName that is written to the database.

This is a concatenated field based on a person's FirstName, Lastname, and office location.

So I have a multibinding on a textBlock...no biggie...works beautifully...but how do I bind the full value of this concatenation to the OfficeDisplayName property? Do I have to have a hidden element that binds to the multibound textbox? I have seen several examples that are almost what I need, but just dont answer the concat databinding question.

+3  A: 

One way is to let the textblock bind directly to OfficeDisplayName and then put the concatenation logic in the OfficeDisplayName property on your viewmodel instead of in the MultiValueConverter. So when ever one of the properties FirstName, LastName, or office location change you'd fire the PropertyChanged event for OfficeDisplayName - i.e. something along the following lines. This way you will not need a converter at all:

class YourViewModel : ViewModel
{
    string _firstName;

    public string FirstName
    {
        get { return _firstName; }
        set
        {
            if (_firstName != value)
            {
                _firstName = value;
                OnPropertyChanged("FirstName");
                OnPropertyChanged("OfficeDisplayName");
            }
        }
    }

    // More properties here
    // ...

    public string OfficeDisplayName
    {
        get { return String.Join(" ", new string[] { _firstName, _lastName, _officeLocation}); }
    }
}

Another way is to pass your viewmodel itself as a parameter to your MultiValueConverter. In your converter you can set the value of OfficeDisplayName directly. I think this way is a bit "hack-ish" but it is a matter of taste. Your code would look like the following:

The binding in XAML:

<MultiBinding Converter="{StaticResource theConverter}" Mode="OneWay">
    <Binding /> <!-- Pass the datacontext as the first parameter -->
    <Binding Path="FirstName" />
    <Binding Path="LastName" />
</MultiBinding>

The converter:

class TheMultiValueConverter : IMultiValueConverter
{
    #region IMultiValueConverter Members

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var viewModel = values[0] as TheViewModel;
        var ret = String.Join(" ", values.Skip(1).Cast<string>().ToArray());
        viewModel.OfficeDisplayName = ret;
        return ret;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}
Jakob Christensen
Ok...this really got me started so I voted you up. However...hehe...I need to save this value to the database but at the same time make sure I am reading an accurate value from the database...so I have to do something in the setter....I am guessing in the long run I may have to pass the viewmodel.
ecathell
+1 for this - <Binding /> <!-- Pass the datacontext as the first parameter -->
akjoshi