目前我想先说低于样品是过于简单化。 假设你已绑定WPF控制。

<Window Title="Window1" Height="300" Width="300">
<Grid>
    <StackPanel>
        <TextBox Text="{Binding Name}" Margin="10"/>
        <Button HorizontalAlignment="Center" 
        Content="Click Me" Margin="5" 
        Padding="2" Click="OnButtonClick" />
    </StackPanel>
</Grid>
</Window>

窗口被绑定到其实现INotifyPropertyChanged并且具有名称设定器在形式Person类

    public string Name 
    {
        get { return _name; }
        set 
        {
            _name = "Some Name";
            OnPropertyChanged("Name");
        }
    }

即。每当用户试图将其从UI改变_name分配“有些名称”。 但这个样品不工作。虽然PropertyChanged事件被触发我在文本框名称更改为某个值按tab迫使焦点移动到文本框按钮和值保持不变。

能否请你解释一下我为什么会发生?据我所知PropertyChanged事件强制UI从属性重读值,并显示它们,但在数据绑定文本框我的示例值不被更新。


再次。我明白,这是执行不力的财产和,但我想重申,这是过于简单化了。 这仅仅是一个样品。 但无论如何,信号的PropertyChanged该属性被更改,应该更新,但事实并非如此。

有帮助吗?

解决方案

在PropertyChanged事件是由文本框忽略,因为它是事件的发起者。

一些澄清:

在文本框(或文本框的结合)知道它是引发剂,因为它在接收同一呼叫PropertyChanged事件。通过这样做异步调用,文本框(或结合)没有办法知道它是发起者,所以它会处理该事件,就好像别人已经更新了它

如果你添加一个文本框2号到您的UI,你会看到,当你编辑1,和周围的其他方式的第二个文本框不会改变。

其他提示

通过Heinzi建议虚设转换器的解决方法(描述这里)不起作用当结合的 UpdateSourceTrigger 的PropertyChanged 。但是,如果这是我们所需要的?

看来使结合 - 异步是卓有成效的,e.g:

SelectedIndex="{Binding SelectedIndex, IsAsync=True}"

正如气泡布已经指出的,这是由设计 - 文本框假定如果它设置一个绑定属性为某个值,该设定器将不会改变该值。 根据微软,它们将不改变这种行为,因为这将破坏现有的代码。

如果您的的更改值(是的,有非常充分的理由这样做),你必须使用一种解决方法,例如,加上空转换器。有博客条目(不是我写的),在详细描述了这种技术。

的原因是因为你在二传手硬编码“有些名称”。当你改变文本框的值设置器实际上得到调用,它重新设置“有些名称”作为这样的PropertyValue似乎犯规在UI改变。 把_name = value,事情只会工作,如你预期,

public string MyField  
{  
    get { return _myField; }  
    set {   
        if (_myField == value)  
            return;  

        _myField = value;   

        OnPropertyChanged("MyField");  
    }  
}  

这是正确执行的属性。

当您更改属性,确保对象完全相同的实例绑定到一个控制。否则,这种变化将被通报,但控制将永远不会得到它,因为该控件没有正确绑定。

在形式更换设定器

        set 
        {
            _name = "Some Name";
            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.DataBind, 
                (SendOrPostCallback)delegate { OnPropertyChanged("Name"); },
                null);
        }

解决问题,但它仍然是开放的。为什么要让异步调用,而不是同步信号,我的财产已被更改。

如果我没有记错的话,默认绑定的文本框的Text属性的行为是双向,所以这应该工作。可以强制它是双向这样在XAML:

<Window Title="Window1" Height="300" Width="300">
  <Grid>
    <StackPanel>
        <TextBox Text="{Binding Name, Mode=TwoWay}" Margin="10"/>
        <Button HorizontalAlignment="Center" 
        Content="Click Me" Margin="5" 
        Padding="2" Click="OnButtonClick" />
    </StackPanel>
  </Grid>
</Window>

请注意在绑定声明Mode=TwoWay

如果不工作的话,我怀疑一个异常被抛出在触发事件的代码,或分配的财产,你应该寻找。


有似乎是你正在调用来改变一个线程不是UI线程值的可能性。如果是这样的话,那么你要么当元帅的呼叫火灾UI线程的属性更改事件,或进行更改到UI线程上的值。

当一个对象绑定到UI元素,更改对象可影响UI必须被UI线程上进行。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top