WPF DataBinding从对象中恢复路径?

时间:2012-08-16 07:00:26

标签: wpf data-binding

我有一个具有多个属性的对象。其中两个用于控制目标文本框的宽度和高度。这是一个简单的例子......

<DataTemplate DataType="{x:Type proj:SourceObject}">
    <TextBox Width="{Binding ObjWidth}" Height="{Binding ObjHeight}"/>
</DataTemplate>

我还想绑定TextBox的Text属性。要绑定的实际属性不是固定的,而是在SourceObject的字段中命名。理想情况下,我想这样做......

<DataTemplate DataType="{x:Type proj:SourceObject}">
    <TextBox Width="{Binding ObjWidth}" Height="{Binding ObjHeight}"
             Text="{Binding Path={Binding ObjPath}"/>
</DataTemplate>

这里的ObjPath是一个字符串,它返回一个对绑定完全有效的路径。但这不起作用,因为您不能使用绑定Binding.Path。我有什么想法可以达到同样的目的吗?

对于更多上下文,我将指出SourceObject是用户可自定义的,因此ObjPath可以随时更新,因此我不能简单地在数据模板中放置固定路径。

1 个答案:

答案 0 :(得分:1)

您可以实施IMultiValueConverter并将此BindingConverter用作文字属性。但是你遇到了问题,Textbox的值只有在ObjPath属性发生变化(路径本身)时才会更新,而不是路径指向的值。如果是这样,那么你可以使用BindingConverter来使用Reflection返回绑定路径的值。

class BindingPathToValue : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value[0] is string && value[1] != null)
        {
            // value[0] is the path
                    // value[1] is SourceObject
            // you can use reflection to get the value and return it
            return value[1].GetType().GetProperty(value.ToString()).GetValue(value[1], null).ToString();
        }
        return null;
    }

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

在资源中使用转换器:

<proj:BindingPathToValue x:Key="BindingPathToValue" />

并在XAML中使用它:

<DataTemplate DataType="{x:Type proj:SourceObject}">
    <TextBox Width="{Binding ObjWidth}" Height="{Binding ObjHeight}">
        <TextBox.Text>
            <MultiBinding Mode="OneWay" Converter="{StaticResource BindingPathToValue}">
                <Binding Mode="OneWay" Path="ObjPath" />
                <Binding Mode="OneWay" Path="." />
            </MultiBinding>
        </TextBox.Text>
    </TextBox>
</DataTemplate>