2
votes

(First of all, I simplified the sample for you to understand.)

I want a editable ComboBox that shows values in inches. The original (source) value is a value in pixels (DIPs), because this is the unit in which the application works internally. The user shouldn't see the value in pixels, but in inches (the measurement unit of the UI). I determined that I must use a converter to translate from pixels to inches and viceversa.

The ComboBox items should also be formatted with "{0} in".

It should appear like this

[ 4 in  |v]
  [ 1 in  ]
  [ 2 in  ]
  [ 3 in  ]
  [ 4 in  ]

But, remember, internally it should work in Pixels! and Be Editable. This is the works part. I have been totally unable to achieve this.

I have this so far:

  <ComboBox IsEditable="True"
            ItemStringFormat="'{}{0} in}'"                  
            Text="{Binding RelativeSource={RelativeSource Self}, Path=SelectedValue, Mode=TwoWay, Converter={StaticResource MyPixelToInchesConverter}, StringFormat='{}{0} in}'}">
            <system:Double>1</system:Double>
            <system:Double>2</system:Double>
            <system:Double>3</system:Double>
  </ComboBox>

The problem? When you select an item, it's not formatted. And when you write a number in the editable region of the ComboBox, it's not formatted, too.

So, what is the best way for a ComboBox to format items even when the user enters a non-existent value??

Thanks!

1

1 Answers

0
votes

Probably a bit late, but I found that setting the Text property to use a binding can work, with a bit of a kludge. In my case I was working with a Currency value, but the same principles should apply

Text = {Binding Path=Indemnity, StringFormat=C0}

However, entering a text value not in the list still exhibits the problem that the StringFormat is not applied (for some strange reason known only to the MS folks who designed this).

To work around this, I added a LostFocus handler that simply writes an incorrect value, followed by writing the correct value again - at which stage the StringFormat is applied:

private void IndemnityCombo_LostFocus(object sender, RoutedEventArgs e)
{
    var vm = this.DataContext as RatesViewModel;    // A view model class
    if (vm != null) {
        decimal indemnity = vm.Indemnity;
        vm.Indemnity = indemnity + 1M;
        vm.Indemnity = indemnity;
    }
}

It's not elegant, but it does the job for me. Hope it can be useful to other users.