WPF绑定OneWayToSource在更改DataContext时将源属性设置为“”

str*_*000 5 c# wpf xaml binding

我设置了目标控件的DataContext时,OneWayToSource绑定的行为异常。源的属性被设置为默认值,而不是目标控件的属性值。

我在标准WPF窗口中创建了一个非常简单的程序来说明我的问题:

XAML

<StackPanel>
  <TextBox x:Name="tb"
    Text="{Binding Path=Text,Mode=OneWayToSource,UpdateSourceTrigger=PropertyChanged}"
    TextChanged="TextBox_TextChanged"/>

  <Button Content="Set DataContext" Click="Button1_Click"/>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

MainWindow.cs

public partial class MainWindow : Window
{
   private ViewModel _vm = new ViewModel();

   private void Button1_Click(object sender, RoutedEventArgs e)
   {
      Debug.Print("'Set DataContext' button clicked");
      tb.DataContext = _vm;
   }

   private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
   {
      Debug.Print("TextBox changed to " + tb.Text);
   }
}
Run Code Online (Sandbox Code Playgroud)

ViewModel.cs

public class ViewModel
{
   private string _Text;
   public string Text
   {
      get { return _Text; }
      set
      {
         Debug.Print(
            "ViewModel.Text (old value=" + (_Text ?? "<null>") + 
            ", new value=" + (value ?? "<null>") + ")");
         _Text = value;
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

TextBox tb以空的DataContext开始,因此,绑定不希望做任何事情。因此,如果我在文本框中键入内容,例如说“ X”,则ViewModel.Text属性将保持为空。

如果我随后单击Set DataContext按钮,则期望该ViewModel.Text属性设置为该属性的“ X” TextBox.Text。而是将其设置为“”。当然,绑定是有效的,因为如果我随后在文本框中的“ X”之后键入“ Y”,则会将ViewModel.Text属性设置为“ XY”。

这是输出的示例(由于评估的顺序,最后两行是违反直觉的,但肯定在输入“ Y”后都立即出现):

将TextBox更改为X
单击“设置DataContext”按钮的
ViewModel.Text(旧值= <null>,新值=)
ViewModel.Text(旧值=,新值= XY)
TextBox更改为XY

ViewModel.Text设置DataContext时,为什么将属性设置为“”而不是“ X”?

我究竟做错了什么?我想念什么吗?我是否对绑定有误解?

编辑:我希望输出是:

TextBox更改为X
单击“ Set DataContext”按钮,单击
ViewModel.Text(旧值= <null>,新值= X
ViewModel.Text(旧值= X,新值= XY)
TextBox更改为XY

dev*_*hog 2

它是一个错误,也可能不是。微软声称这是设计使然。您首先输入 x,然后通过单击 Button 杀死 DataContext,这就是为什么 TextBox 包含 x 并且您的 viewModel.Text 属性被重新初始化(其为空)。当数据上下文改变时,getter 仍然会被调用。最终你没有机会解决这个问题。

但是,您可以使用两种方式并顺其自然。