一尘不染

.NET 4.0中的OneWayToSource绑定似乎已损坏

c#

OneWayToSource 绑定似乎在.NET 4.0中被破坏

我有一块简单的Xaml

<StackPanel>
    <TextBox Text="{Binding TextProperty, Mode=OneWayToSource}"/>
    <Button/>
</StackPanel>

我后面的代码看起来像这样

public MainWindow()
{
    InitializeComponent();
    this.DataContext = this;
}
private string m_textProperty;
public string TextProperty
{
    get
    {
        return "Should not be used in OneWayToSource Binding";
    }
    set
    {
        m_textProperty = value;
    }
}

在.NET 3.5中,
此方法可能会起作用,除了。将一些文本放入中TextBox,按Tab键使其失去焦点,然后TextProperty使用输入的任何文本进行更新。TextBox

在.NET 4.0中
,如果我在中键入一些文本TextBox,然后按Tab使其失去焦点,则TextBox还原为的值TextProperty(表示
“不应在OneWayToSource绑定中使用” )。这种重新读取是否打算用于OneWayToSource.NET
4.0中的绑定?我只希望TextBox将其价值推向TextProperty而不是相反。

更新
向这个问题添加赏金,因为这已成为我项目中的市长不便之处,我想知道这种情况改变的原因。似乎get在绑定更新源之后调用。这是OneWayToSource.NET
4.0中绑定的理想行为吗?

如是

  • 它在3.5中的工作方式有什么问题?
  • 在什么情况下,这种新行为会更好?

还是 实际上这是一个我们可以希望在将来的版本中修复的错误?


阅读 254

收藏
2020-05-19

共1个答案

一尘不染

Karl
Shifflett的博客和@Simpzon的答案已经涵盖了他们为什么添加此功能,以及为什么对于始终获得设置的属性来说这不是问题。在您自己的代码中,您始终使用具有适当语义的中间属性进行绑定,并使用具有所需语义的内部属性。我将中间属性称为“阻塞”属性,因为它会阻止吸气剂到达您的内部属性。

但是,如果您无权访问要在其上设置属性的实体的源代码并且想要旧的行为,则可以使用转换器。

这是一个具有状态的阻塞转换器:

public class BlockingConverter : IValueConverter
{
    public object lastValue;

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

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        lastValue = value;
        return value;
    }
}

您可以将其用于您的示例,如下所示:

<Grid>
    <Grid.Resources>
        <local:BlockingConverter x:Key="blockingConverter" x:Shared="False"/>
    </Grid.Resources>
    <StackPanel>
        <TextBox Text="{Binding TextProperty, Mode=OneWayToSource, Converter={StaticResource blockingConverter}}"/>
        <Button Content="Click"/>
    </StackPanel>
</Grid>

请注意,由于转换器具有状态,因此每次使用资源时都需要一个单独的实例,为此,我们可以使用x:Shared="False"资源上的属性。

2020-05-19