11

Ok, this is kind of odd but this is basically what I need to do. I have a WPF control that is bound to a Document object. The Document object has a Pages property. So in my ViewModel, I have a CurrentDocument property, and a CurrentPage property.

Now, I have a combobox that I have bound to the CurrentDocument.Pages property and updates the CurrentPage property.

<ComboBox ItemsSource="{Binding CurrentDocument.Pages}"
    DisplayMemberPath="???"
    SelectedItem="{Binding CurrentPage, Mode=TwoWay}">
</ComboBox>

With me so far? All of this is fine except that I need the DisplayMemberPath to show "Page 1", "Page 2", etc.....

I tried creating a converter such as this:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    string pageNumber = "Page {0}";
    return string.Format(pageNumber, value);
}

And tried to bind DisplayMemberPath to it like this:

DisplayMemberPath="{Binding RelativeSource={RelativeSource Self}, Path=Index, Converter={StaticResource pgTitleConv}}"

But it still wouldn't show up in the combo box text!!!

There is no "Index" property but I don't know how to do this...How do I access the index of the item that the combobox is binding to...??????

Andy
  • 30,088
  • 6
  • 78
  • 89
Jeffrey T. Whitney
  • 111
  • 1
  • 1
  • 4

2 Answers2

24

try this:

<ComboBox.ItemTemplate>
  <DataTemplate>
    <TextBlock Text="{Binding Converter={StaticResource pgTitleConv}}"/>
  </DataTemplate>
</ComboBox.ItemTemplate>

and in your valueconverter, if you can access the pages collection, you can use CurrentDocument.Pages.IndexOf(value) to get the index of the bound item. I'm sure there is a better way though.

Botz3000
  • 39,020
  • 8
  • 103
  • 127
  • 1
    Works but using a converter impacts performance. I adapted above to use the binding StringFormat feature. eg. –  Apr 10 '13 at 11:59
  • @Darren Just curious, how much performance difference is there? How did you measure it? And where is the page index in the format string? – Botz3000 Apr 10 '13 at 12:30
  • His example shows he's formatting a int value (page number/index) "string.Format(pageNumber, value);". Your example demonstrates you don't need to provide a element name (Path=) to get the int value. So using the Binding's string formatter option to add the "Page" text in front of it was easy way to do (I was doing "Week x"). –  Apr 10 '13 at 14:13
  • Performance: Getting Binding to format the value using own format function would reduce code. I could be wrong but I presume calling and executing the external value converter will add more code. I voted up your answer as it was the one that shows you don't need the element name which was the thing that stumped me. –  Apr 10 '13 at 14:13
  • @Darren More code doesn't necessarily mean worse performance. However how would you get at the index of a page in its parent collection just using StringFormat? I mean i prefer StringFormat whenever possible, but for cases like this it can't really replace a Converter. – Botz3000 Apr 10 '13 at 14:20
0

Ok, Thanks to Botz3000 I figured out how to do this. (It's a bit wiggy, but it works fine.)

Suddenly, it came to me: the Page object has a Document object!! Doh!!

So, my PageTitleConvert just does this:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    if (value != null)
    {
        ImGearPage page = (ImGearPage)value;
        ImGearDocument doc = page.Document;
        int pageIndex = doc.Pages.IndexOf(page);
        pageIndex++;
        return string.Format("Page {0}", pageIndex);
    }
    return null;
}
Orion Edwards
  • 121,657
  • 64
  • 239
  • 328
Jeffrey T. Whitney
  • 111
  • 1
  • 1
  • 4