简体   繁体   中英

WPF Binding with property index?

I have a project in which I need to bind the background of a TextBox to a value in an array where the index is a property in the DataContext:

Binding backgroundBinding= new Binding();
backgroundBinding.Path = new PropertyPath($"Elements[{Index}].Value");

I've been creating the binding in the codebehind, but want to find a better and more elegant way to do it. Would I have to create a custom converter, or is there some way to reference the Index property in the XAML?

So you've got two options here. I think you're asking for the first one. I've set up two properties in my viewmodel - one for the array of colours, and then one for the index I want to use. I'm binding to them through a MultiConverter to return the correct colour from the array. This will allow you to update your selected index at runtime, and have the background change to the newly selected colour. If you just want a static index that never changes, you should use implement IValueConverter instead of a IMultiValueConverter , and then pass the index in using the ConverterParameter property.

As a side note, I've chosen to implement the array as type Color . SolidColorBrush objects are expensive and doing it this way will help reduce that cost.

public class ViewModel : INotifyPropertyChanged
{
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private Color[] _backgroundColours = new Color[] { Colors.AliceBlue, Colors.Aqua, Colors.Azure };
    public Color[] BackgroundColours
    {
        get => _backgroundColours;
        set
        {
            _backgroundColours = value;
            OnPropertyChanged();
        }
    }

    private int _backgroundIndex = 1;

    public int ChosenIndex
    {
        get => _backgroundIndex;
        set
        {
            _backgroundIndex = value;
            OnPropertyChanged();
        }
    }
}

...

public class BackgroundConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var backgroundColours = values[0] as Color[];
        var chosenIndex = (int)values[1];

        return new SolidColorBrush(backgroundColours[chosenIndex]);
    }

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

...

<Grid>
    <Grid.DataContext>
        <local:ViewModel />
    </Grid.DataContext>
    <Grid.Resources>
        <local:BackgroundConverter x:Key="backgroundConverter"/>
    </Grid.Resources>
    <TextBox>
        <TextBox.Background>
            <MultiBinding Converter="{StaticResource backgroundConverter}">
                <Binding Path="BackgroundColours" />
                <Binding Path="ChosenIndex" />
            </MultiBinding>
        </TextBox.Background>
    </TextBox>
</Grid>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM