WPF数据绑定源可以包含参数吗?

时间:2016-05-06 18:33:18

标签: wpf

我可以将索引号传递到此列表(SomeList)吗?

FontSize="{Binding FontSize, Source={x:Static ut:ViewSetupData.SomeList}, FallbackValue=12}"

1 个答案:

答案 0 :(得分:2)

您可以在Path

中添加常量索引器
{Binding Path=[(sys:Int32)0], Source={x:Static ut:ViewSetupData.SomeList}}

但是您无法绑定Binding的属性,因此无法在其中填充参数。但是,您可以在MultiBinding中组合多个绑定,因此您可以使用具有多值转换器的其中一个:

C#:

public class IListIndexerConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        //  You might want a little more error-checking than this...
        return ((IList)values[0])[(int)values[1]];
    }

    public virtual object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return null;
    }
}

XAML:

<TextBlock>
    <TextBlock.Resources>
        <local:IListIndexerConverter x:Key="ListIndexer" />
    </TextBlock.Resources>
    <TextBlock.Text>
        <MultiBinding Converter="{StaticResource ListIndexer}">
            <Binding Source="{x:Static ut:ViewSetupData.SomeList}" />
            <Binding
                ElementName="MyComboBox"
                Path="SelectedIndex" 
                />
        </MultiBinding>
    </TextBlock.Test>
</TextBlock>

更新

当您将此标记为解决方案时,我正在编写一个更完整的解决方案,以满足您从列表项中获取属性的需求:

C#:

public class ListItemPropertyGetter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        try
        {
            var list = values[0] as IList;
            var index = (int)(values[1] ?? 0);
            var propname = values[2] as String;

            object item = list[index];

            var prop = item.GetType().GetProperty(propname);

            var propvalue = prop.GetValue(item);

            return propvalue;
        }
        catch
        {
            return null;
        }
    }

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

    //  Gotta put these somewhere
    public static List<FontSizeThing> FontSizeThings { get; } =
        new List<FontSizeThing>
        {
            new FontSizeThing(10),
            new FontSizeThing(10.5),
            new FontSizeThing(11),
            new FontSizeThing(12),
            new FontSizeThing(14),
            new FontSizeThing(15),
        };
}

public class FontSizeThing {
    public FontSizeThing(double n) { FontSize = n; }
    public double FontSize { get; set; }
}

XAML:

<ComboBox x:Name="FontSizeOptionCombo">
    <sys:Int32>0</sys:Int32>
    <sys:Int32>1</sys:Int32>
    <sys:Int32>2</sys:Int32>
    <sys:Int32>3</sys:Int32>
    <sys:Int32>4</sys:Int32>
</ComboBox>
<TextBlock Text="Testing">
    <TextBlock.Resources>
        <hconv:ListItemPropertyGetter x:Key="ListItemPropertyGetter" />
    </TextBlock.Resources>
    <TextBlock.FontSize>
        <MultiBinding Converter="{StaticResource ListItemPropertyGetter}" StringFormat="{}{0}">
            <Binding Source="{x:Static hconv:ListItemPropertyGetter.FontSizeThings}" />
            <Binding ElementName="FontSizeOptionCombo" Path="SelectedItem" />
            <Binding Source="FontSize" />
        </MultiBinding>
    </TextBlock.FontSize>
</TextBlock>

最终更新

请注意,如果我只使用FontThings本身填充FontSizeOptionCombo,我可以非常简单地绑定这样:

<ComboBox 
    x:Name="OtherCombo" 
    ItemsSource="{x:Static hconv:ListItemPropertyGetter.FontSizeThings}" 
    DisplayMemberPath="FontSize" 
    FontSize="{Binding SelectedItem.FontSize, ElementName=OtherCombo, FallbackValue=20}"
    />

如果这与你正在做的事情相符,它是迄今为止最好的方式。