我在silverlight中有一个文本框,定义如下:
<TextBox x:Name="hedtextBox" DataContext="{Binding HedFileInfo}" Text="{Binding Name}" Width="100" Grid.Column="1" Margin="2,0,2,0" />
我的视图模型有一个名为HedFileInfo
的FileInfo
对象。并且,我在文本框旁边有一个Button
,当单击它时,启动OpenFileDialog
,如下所示
private void HedBrowseButtonClick(object sender, RoutedEventArgs e)
{
var ofd = new OpenFileDialog { Filter = "CSV Files (.csv)|*.csv" };
var result = ofd.ShowDialog();
// Process open file dialog box results
if (result != true) return;
hedTextBox.DataContext = ofd.File;
}
我这样做是因为silverlight不让我访问OpenFileDialog
中的FullName
所有路径(网络驱动器等)。如果我只是将ViewModel
中的string
绑定到TextBox
,我将无法获得字符串中的完整路径。TextBox
文本绑定到Name
字段,但是当我在按钮单击事件中设置DataContext时,视图模型中的FileInfo没有更新这有道理吗?
我想你自己得出了正确的答案。如果您希望源对象(HedFileInfo
)的属性在DataContext
属性被修改时发生变化,您需要将绑定模式更改为TwoWay
。这是完全正常的,它应该是这样工作的。
考虑最基本的绑定:-
<TextBox Text="{Binding Description}" />
这段代码为TextProperty
依赖属性在TextBox
对象上设置了一个绑定。只要Description
属性发生变化,这个绑定就会将Description
的值赋给TextBox.Text
属性。但是,还有另外两种方法可以设置Text
属性。用户可以输入当前存在的内容,或者代码可以为Text
属性赋值。因此,TextBox.Text
属性可能与Description
具有不同的值。在默认的OneWay
模式下,源对象的Description
属性不会被修改。
现在改为:-
<TextBox Text="{Binding Description, Mode-TwoWay}" />
每当用户输入新的文本或代码直接修改Text
属性时,绑定现在将通过更新源对象上的Description
属性来响应。
DataContext
属性及其绑定的行为完全相同。: -
<TextBox DataContext="{Binding HedFileInfo}" Text="{Binding Name}" />
只要源视图模型中HedFileInfo
的值发生变化(假设实现了INotifyPropertyChanged
),那么DataContext
的值就会发生变化。然而,当代码直接修改DataContext
的值时,绑定(处于OneWay
模式)不会更新源视图模型。
改成:-
<TextBox DataContext="{Binding HedFileInfo, Mode=TwoWay}" Text="{Binding Name}" />
,现在它可以像你想的那样工作了。当代码直接更改DataContext
值时,绑定将通过更新源视图模型的HedFileInfo
属性来响应。