0

我在 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);
            }
        }
    }
4

1 回答 1

6

TextBox.Text设置属性时 ViewModel 属性未更新的原因是Binding 的UpdateSourceTrigger属性设置为LostFocus。这是TextBox.Text属性绑定的默认值。

如果将其更改为PropertyChanged, ViewModel 属性将按预期更新:

<TextBox Text="{Binding ConfigurationPath, UpdateSourceTrigger=PropertyChanged}"/>

当然,WPF 绑定系统会注意避免无限更新循环。

于 2013-02-08T21:38:50.153 回答