【问题标题】:WPF Cyclic ConverterWPF 循环转换器
【发布时间】:2014-02-14 19:59:17
【问题描述】:

当您拖动滑块时,您会得到一个 ConvertBack(预期),但为什么我会在此之后直接得到一个“Convert”?我只希望 Convert 在它第一次初始化时被调用,或者如果它正在引发属性更改通知,但它没有。

<Window x:Class="WpfApplication10.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:WpfApplication10"
        Title="MainWindow">
    <Slider Value="{Binding Value, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Converter={l:Converter}}"/>
</Window>


public class Converter : MarkupExtension, IValueConverter
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value;
    }
}

public partial class MainWindow : Window
{
    public double Value { get; set; }

    public MainWindow()
    {
        DataContext = this;
        InitializeComponent();
    }
}

【问题讨论】:

    标签: wpf converter


    【解决方案1】:

    这很可能是因为您使用的是 .NET 4,它稍微改变了绑定的工作方式:http://karlshifflett.wordpress.com/2009/05/27/wpf-4-0-data-binding-change-great-feature/

    虽然在 4 之前绑定不会更新回来(假设它不需要),但新行为是默认执行此操作。链接的博客中解释了基本原理。

    编辑:我想我应该问一下您是否有不希望它转换回来的原因,或者只是出于好奇?如果您需要防止转换回来,最明确的策略可能是跟踪您上次转换的值以鹦鹉回:

    public class Converter : MarkupExtension, IValueConverter
    {
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
    
    public object lastValue;
    
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return lastValue;
    }
    
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        lastValue = value;
        return value;
    }
    }
    

    还有将绑定设置为 OneWayToSource 的选项,这将防止它设置回滑块值...假设您不需要将数据推回滑块。

    【讨论】:

    • 这出现在 4.5 中用 3.5 编写的构建代码中。在少数情况下,传递给 Convert/ConvertBack 的值并不完全相同(例如数字类型中的精度损失),并且会导致奇怪的行为。如果您可以选择退出新行为,那就太好了。
    • 这有点令人惊讶,我不认为这种行为会很愚蠢——你的意思是浮点数/双精度数的精度很奇怪吗?浮点/双精度单向为 1.5 而另一向为 1.499999999 是正常的,这是避免使用它们的一个原因,除非您真的有意这样做。如果是这种情况,您是否考虑过使用小数代替?
    • 目前我只是在 ConvertBack 中缓存“值”,类似于您的建议。十进制是另一种选择,但会破坏很多现有代码,所以缓存破解现在就可以了。
    • 我们在内部使用了一堆浮点数,这在我进行几何计算时是一个巨大的痛苦。我建议编写这样的方法:private const float EPSILON = 0.0001f; private bool NearlyEqual(float leftValue, float rightValue, float epsilon = EPSILON) { return Maths.Abs(leftValue - rightValue) &lt; epsilon; } 确保将 epsilon 调整为能够捕捉计算中不准确的值,它通常可以比我的示例小得多。
    猜你喜欢
    • 1970-01-01
    • 2021-03-12
    • 2014-12-11
    • 2018-02-22
    • 2014-12-18
    • 2017-04-26
    • 2018-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多