OneWayToSource 绑定在 .NET 4.0 中似乎已损坏 [英] OneWayToSource Binding seems broken in .NET 4.0

查看:64
本文介绍了OneWayToSource 绑定在 .NET 4.0 中似乎已损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我有这个简单的 Xaml

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

我后面的代码是这样的

public MainWindow(){初始化组件();this.DataContext = this;}私有字符串 m_textProperty;公共字符串 TextProperty{得到{返回不应在 OneWayToSource 绑定中使用";}放{m_textProperty = 值;}}

在 .NET 3.5 中,这与您可能不同.在 TextBox 中放入一些文本,按 Tab 键使其失去焦点,TextProperty 更新为在 TextBox 中输入的任何文本/p>

在 .NET 4.0 中,如果我在 TextBox 中输入一些文本,然后按 Tab 使其失去焦点,TextBox 将恢复TextProperty 的值(意思是不应在 OneWayToSource 绑定中使用").重新阅读是否适用于 .NET 4.0 中的 OneWayToSource 绑定?我只希望 TextBox 将其值推送到 TextProperty 而不是相反.

更新
向这个问题添加赏金,因为这已经成为我项目中的主要不便,我想知道这种情况发生变化的原因.似乎 get 在 Binding 更新源之后被调用.这是 .NET 4.0 中 OneWayToSource 绑定所需的行为吗?

如果是

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

或者这实际上是我们希望在未来版本中修复的错误吗?

解决方案

Karl Shifflett 的博客和 @Simpzon 的回答已经涵盖了他们添加此功能的原因,以及为什么对于始终获取设置内容的属性来说这不是问题.在您自己的代码中,您始终使用具有正确绑定语义的中间属性,并使用具有所需语义的内部属性.我将中间属性称为阻塞"属性,因为它会阻止 getter 访问您的内部属性.

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

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

公共类 BlockingConverter : IValueConverter{公共对象 lastValue;公共对象转换(对象值,类型目标类型,对象参数,CultureInfo 文化){返回最后一个值;}公共对象 ConvertBack(对象值,类型目标类型,对象参数,CultureInfo 文化){lastValue = 值;返回值;}}

您可以像这样将其用于示例:

<网格.资源><local:BlockingConverter x:Key="blockingConverter" x:Shared="False"/></Grid.Resources><堆栈面板><TextBox Text="{Binding TextProperty, Mode=OneWayToSource, Converter={StaticResource blocksConverter}}"/><按钮内容="点击"/></StackPanel></网格>

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

OneWayToSource Binding seems broken in .NET 4.0

I have this simple piece of Xaml

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

And my code behind looks like this

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;
    }
}

In .NET 3.5 this works as you might except. Put some text in the TextBox, press Tab to make it lose Focus, and the TextProperty updates with whatever text that was entered in the TextBox

In .NET 4.0, if I type some text in the TextBox and then press Tab to make it lose Focus, the TextBox reverts to the value for TextProperty (meaning "Should not be used in OneWayToSource Binding"). Is this re-reading intended for a OneWayToSource Binding in .NET 4.0? I just want the TextBox to push its value into the TextProperty and not the other way around.

Update
Adding a Bounty to this question as this has become a mayor inconvenience in my project and I would like to know the reason that this has changed. It seems that get is called after the Binding has updated the source. Is this the desired behavior for a OneWayToSource Binding in .NET 4.0?

If Yes

  • What was the problem with the way it worked in 3.5?
  • In what scenarios is this new behavior better?

Or is this in fact a bug that we can hope to get fixed in a future release?

解决方案

Karl Shifflett's blog and @Simpzon's answer already cover why they added this feature and why it is not a problem for properties that always get what was set. In your own code you always use an intermediate property that has the proper semantics for binding and use an internal property that has the semantics you want. I would call the intermediate property a "blocking" property because it blocks the getter from reaching your internal property.

But in the case where you don't have access to the source code for the entity that you are setting the property on and you want the old behavior, you can use a converter.

Here is a blocking converter with state:

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;
    }
}

and you can use it for your example like this:

<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>

Note that because the converter has a state you need a separate instance each time the resource is used and for this we can use the x:Shared="False" attribute on the resource.

这篇关于OneWayToSource 绑定在 .NET 4.0 中似乎已损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆