Search code examples
c#wpfxamldata-bindingstringcollection

WPF binding textbox to item of a string collection


I have a StringCollection in my settings and want to bind 1 of the items to a label.

This is how it works.

xmlns:p="clr-namespace:MyNamespace.Properties" 
<Label Content="{Binding Path=MyStringCollection.[2], Source={x:Static p:Settings.Default}}" />

But I want to bind the index to another value and thought that this should work. But it doesnt.

<Label Content="{Binding Path=MyStringCollection.[{Binding SelectedIndex Source={x:Static p:Settings.Default}}], Source={x:Static p:Settings.Default}}" />

Can someone help me?


Solution

  • With stock WPF you'll need to use an IMultiValueConverter:

    public class IndexedValueConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType,
            object parameter, CultureInfo culture)
        {
            if (values.Length < 2) return null;
            var index = Convert.ToInt32(values[1], culture);
            var array = values[0] as Array;
            if (array != null) return array.GetValue(index);
            var list = values[0] as IList;
            if (list != null) return list[index];
            var enumerable = values[0] as IEnumerable;
            if (enumerable != null)
            {
                int ii = 0;
                foreach (var item in enumerable)
                {
                    if (ii++ == index) return item;
                }
            }
    
            return null;
        }
    
    // ... Implement ConvertBack as desired
    

    Then in your XAML:

    <Label>
        <Label.Resources>
            <local:IndexedValueConverter x:Key="Indexer" />
        </Label.Resources>
        <Label.Content>
            <MultiBinding Converter="{StaticResource Indexer}">
                <Binding Path="MyStringCollection"
                         Source="{x:Static p:Settings.Default}" />
                <Binding Path="SelectedIndex"
                         Source="{x:Static p:Settings.Default}" />
            </MultiBinding>
        </Label.Content>
    </Label>