【问题标题】:IValueConverter with Bound Dependency Properties具有绑定依赖属性的 IValueConverter
【发布时间】:2012-04-16 10:46:45
【问题描述】:

我需要在运行时根据要绑定的对象中标识的单位系统确定某些绑定TextBlocksStringFormat

我有一个我想绑定到的具有依赖属性的转换器。 Bound 值用于确定转换过程。

public class UnitConverter : DependencyObject, IValueConverter
{
    public static readonly DependencyProperty IsMetricProperty =
        DependencyProperty.Register("IsMetric", typeof(bool), typeof(UnitConverter), new PropertyMetadata(true, ValueChanged));

    private static void ValueChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        ((UnitConverter)source).IsMetric = (bool)e.NewValue;
    }

    public bool IsMetric
    {
        get { return (bool)this.GetValue(IsMetricProperty); }
        set { this.SetValue(IsMetricProperty, value); }
    }

    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (IsMetric)
            return string.Format("{0:0.0}", value);
        else
            return string.Format("{0:0.000}", value);
    }

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我声明转换器

<my:UnitConverter x:Key="Units" IsMetric="{Binding Path=IsMetric}"/>

并绑定TextBlock

<TextBlock Text="{Binding Path=Breadth, Converter={StaticResource Units}}" Style="{StaticResource Values}"/>

总是这样,我得到以下错误:

System.Windows.Data 错误:2:找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement。绑定表达式:路径=IsMetric;数据项=空;目标元素是“UnitConverter”(HashCode=62641008);目标属性是“IsMetric”(类型“布尔”)

我想这是在我设置数据上下文之前初始化的,因此没有任何东西可以绑定IsMetric 属性。我怎样才能达到预期的效果?

【问题讨论】:

    标签: c# wpf data-binding ivalueconverter


    【解决方案1】:

    如果BreadthIsMetric是同一个数据对象的属性,您可以将MultiBindingmulti value converter结合使用:

    <TextBlock>
        <TextBlock.Text>
            <MultiBinding Converter="{StaticResource UnitMultiValueConverter}">
                <Binding Path="Breadth" />
                <Binding Path="IsMetric" />
            </MultiBinding>
        </TextBlock.Text>
    </TextBlock>
    

    使用这样的转换器:

    public class UnitMultiValueConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            double value = (double)values[0];
            bool isMetric = (bool)values[1];
            string format = isMetric ? "{0:0.0}" : "{0:0.000}";
            return string.Format(format, value);
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    您的方法的问题是,当 UnitConverter 被声明为资源时,它没有 DataContext,以后也永远不会得到。

    还有一件更重要的事情:UnitConverter.IsMetricValueChanged 回调是无稽之谈。它再次设置刚刚更改的相同属性。

    【讨论】:

    • 我想避免这种情况,因为我有数百个 TextBlock,我不想全部修改。
    • 谢谢伙计,是的,我意识到我只是在设置相同的属性,如果它曾经被调用过,那就是!然而,MultiBinding 效果很好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    • 2016-01-22
    • 2012-11-08
    • 2012-08-01
    • 2017-12-24
    • 1970-01-01
    • 2014-08-31
    相关资源
    最近更新 更多