Malka
Malka

Reputation: 51

Is there a way to bind 2 (or more) WPF items to a single property in C#?

My class contains an address property (string type), but my WPF window contains a few text boxes for the address (house number, street name and optional second line of address - the town and postcode do have separate fields in the class). I would like to get them all into the single address string in the class, separated by commas (eg. "43, Whitefield Road, Princesshire"). Is there a way to do so by binding, or only manually in the code?

enter image description here

Upvotes: 2

Views: 561

Answers (3)

ChrisF
ChrisF

Reputation: 137148

If you create an Address object with separate fields for the house number, street name, post code etc. you can bind to each individually.

If you want to print out the whole address you then create a read only property which combines the various parts of the address into a single string:

public string SingleLineFormat
{
    get
    {
        return string.Format("{0} {1}, {2}, {3}", this.Number, this.Street, this.Town, this.PostCode);
    }
}

You could even have different versions that return the string formatted across several lines or with different combinations of the address as required.

public string MultiLineFormat
{
    get
    {
        return string.Format("{0} {1}{4} {2}{4} {3}", this.Number, this.Street, this.Town, this.PostCode, Environment.NewLine);
    }
}

Upvotes: 0

Kylo Ren
Kylo Ren

Reputation: 8813

use MultiBinding:

The syntax for address textbox text binding would be:

<TextBox Width="100" >
        <TextBox.Text>
            <MultiBinding Converter="{StaticResource YourAddressConverter}">
                //order below bindings as you want them in the array passed to converter
                <Binding ElementName="Houseblock" Path="Text"/>
                <Binding ElementName="streetblock" Path="Text"/>
                 .......................
                <Binding ElementName="townblock" Path="Text"/>
            </MultiBinding>
        </TextBox.Text>
    </TextBox>

where using elementbinding the text of other textboxes is binded to finaltextbox(address) and YourAddressConverter is a converter that will contain the login of concatenation of address components as below in it's convert method.

public class YourAddressConverter : IMultiValueConverter
{

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return values[0].ToString() + " " + values[1].ToString();
    }

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

It's the simplest and best solution.

Upvotes: 0

JT_
JT_

Reputation: 513

Bind all the fields to the Address property on your class, then use a value converter to determine which components of the address are applicable. In the converter have a property allowing you to determine which substring to manipulate:

public class AddressSeparatorConverter : IValueConverter
{
    ///<summary>
    /// Index of the substring element of the address to be manipulated (read/edited).
    ///</summary>
    public int SubStringIdx { get; set; }

    ...
}

Then when you perform the conversion, you simply split the string using the , delimiter and return the substring as specified by the SubStringIdx:

address.Split(',')[SubStringIdx]

As you're binding to an editable control, you will need to make sure you provide implementations for both IValueConverter.Convert and IValueConverter.ConvertBack methods.

To take this one step further, you could provide different converter definitions in your Converters.xaml file to handle the various subcomponents of address:

<converters:AddressSeparatorConverter x:Key="AddressToHouseNumberConverter" SubStringIdx="0"/>
<converters:AddressSeparatorConverter x:Key="AddressToStreetNameConverter" SubStringIdx="1"/>
...

Then when binding to your control you would call the appropriate converter by its key:

<TextBox Text="{Binding Address, Converter={StaticResource AddressToStreetNameConverter}}"/>

I don't have access to an IDE right now so please accept the code snippets may not be 100% right but you should get the gist of it.

Upvotes: 1

Related Questions