我在 WPF 窗口中有一个文本框,我从后面的代码中填充(在用户从 OpenFileDialog.
尽管我的 TextBox.Text 绑定到我的 ViewModel 类中的 String 属性,但当文本设置到 TextBox.Text 时,该属性不会被填充。
如果我在 TextBox 中键入内容,则该属性会被填充,因此必须在用户输入期间触发某些事件或发生某些事情,而不是在我通过代码设置值时发生。
我缺少正确绑定的步骤是什么?
此外,属性上的 set 方法是在属性更改时调用,还是在 UI 上调用?或两者?如果更改 UI 调用 set 方法,该方法会触发 PropertyChanged 事件以更新 UI,那么是什么阻止了这种循环?
(我知道我可以直接设置属性,但我觉得我对绑定缺乏了解,我希望这将有助于填补一些空白。)
我的示例代码:
<Window x:Class="ConfigurationViewer.ViewerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ConfigurationViewer"
Title="Configuration Viewer" Height="512" Width="714" >
<Window.DataContext>
<local:TaskViewModel x:Name="_model"/>
</Window.DataContext>
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<TextBlock Text="Configuration file" Margin="2" VerticalAlignment="Center" />
<TextBox Height="29" Margin="2" Name="textFilePath" Width="277" Text="{Binding Path=ConfigurationPath}" />
<Button Content="Browse ..." Margin="2" Name="buttonBrowseFile" Width="98" Click="buttonBrowseFile_Click" />
<Button Content="Open" Margin="2" Name="buttonOpenFile" Width="98" Click="buttonOpenFile_Click" />
</StackPanel>
</DockPanel>
</Window>
public partial class ViewerWindow : Window
{
public ViewerWindow()
{
InitializeComponent();
}
private void buttonBrowseFile_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openDialog = new OpenFileDialog();
openDialog.Multiselect = false;
openDialog.InitialDirectory = textFilePath.Text;
Nullable<Boolean> ok = openDialog.ShowDialog();
if (ok == true)
{
textFilePath.Text = openDialog.FileName;
}
}
private void buttonOpenFile_Click(object sender, RoutedEventArgs e)
{
}
}
public class TaskViewModel : INotifyPropertyChanged
{
private String _configurationPath = String.Empty;
public String ConfigurationPath
{
get { return _configurationPath; }
set
{
_configurationPath = value;
OnPropertyChanged("ConfigurationPath");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(String prop)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(prop);
handler(this, e);
}
}
}