C# ViewModel属性在更改文本框文本时未更新

C# ViewModel属性在更改文本框文本时未更新,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我在UserControl中有一个文本框,它绑定到主窗口的ViewModel中的属性 现在,当我在Textbox中键入内容时,它会更新viewmodel中的属性,但如果我在代码隐藏中更改Textbox的文本,则viewmodel属性不会更新 实际上,textbox是从FileDialog中获取值的,当我单击按钮时会打开FileDialog,所以textbox是从代码隐藏中获取文本的 UserControl XAML: <StackPanel Orientation="Horizontal"

我在UserControl中有一个文本框,它绑定到主窗口的ViewModel中的属性

现在,当我在Textbox中键入内容时,它会更新viewmodel中的属性,但如果我在代码隐藏中更改Textbox的文本,则viewmodel属性不会更新

实际上,textbox是从FileDialog中获取值的,当我单击按钮时会打开FileDialog,所以textbox是从代码隐藏中获取文本的

UserControl XAML:

<StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Left">
    <TextBox x:Name="TextBoxFileOrFolder" Text="{Binding FolderOrFileName}" Grid.Row="1" Width="200" Height="100" HorizontalAlignment="Left"></TextBox>
    <Button x:Name="ButtonRun" Content="Run" Click="ButtonRun_OnClick" Width="200" Height="100" Margin="10"></Button>
</StackPanel>
视图模型:

public class MainViewModel: INotifyPropertyChanged
{
    public MainViewModel()
    { }

    private string folderOrFileName;

    public string FolderOrFileName
    {
        get { return folderOrFileName; }
        set
        {
            if (folderOrFileName!=value)
            {
                folderOrFileName = value;
                RaisePropertyChanged();
            }
        }
    }

    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Raises the property changed.
    /// </summary>
    /// <param name="propertyName">Name of the property.</param>
    protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    # endregion
}
public class MainViewModel : INotifyPropertyChanged
{
    public MainViewModel()
    {
        ChangeFileName = new DelegateCommand(OnChangeFileName);
    }

    public ICommand ChangeFileName { get; private set; }

    private void OnChangeFileName(object param)
    {
        FolderOrFileName = "FileName" + new Random().Next();
    }

    private string folderOrFileName;
    ...

确保绑定设置为双向-UI->VM和VM->UI

<TextBox x:Name="TextBoxFileOrFolder" Text="{Binding FolderOrFileName, Mode=TwoWay}" Grid.Row="1" Width="200" Height="100" HorizontalAlignment="Left"></TextBox>

确保绑定设置为双向-UI->VM和VM->UI

<TextBox x:Name="TextBoxFileOrFolder" Text="{Binding FolderOrFileName, Mode=TwoWay}" Grid.Row="1" Width="200" Height="100" HorizontalAlignment="Left"></TextBox>
如果绑定到文本属性,则应在ViewModel中设置属性以更改TextBox的值:

在您的情况下,应该使用命令修改数据

1您应该创建从ICommand继承的类:

最后,您应该向视图中的Button.Command属性添加绑定:

<Button x:Name="ButtonRun" Content="Run" Command="{Binding ChangeFileName}" Width="200" Height="100" Margin="10"></Button>
如果绑定到文本属性,则应在ViewModel中设置属性以更改TextBox的值:

在您的情况下,应该使用命令修改数据

1您应该创建从ICommand继承的类:

最后,您应该向视图中的Button.Command属性添加绑定:

<Button x:Name="ButtonRun" Content="Run" Command="{Binding ChangeFileName}" Width="200" Height="100" Margin="10"></Button>
但是如果我在代码隐藏中更改Textbox的文本,viewmodel属性不会更新

这是因为如果在代码隐藏中设置文本框的Text属性,则会覆盖绑定。因此,在更新视图时,指向视图模型的链接将消失,因此没有任何内容可以更新它。而且,当视图模型更新值时,视图也不会更新

要解决这个问题,只需不设置在代码背后有绑定的属性即可

与其在代码隐藏中处理按钮事件并更新视图,不如将按钮命令绑定到视图模型并更新视图模型中的FolderOrFileName

但是如果我在代码隐藏中更改Textbox的文本,viewmodel属性不会更新

这是因为如果在代码隐藏中设置文本框的Text属性,则会覆盖绑定。因此,在更新视图时,指向视图模型的链接将消失,因此没有任何内容可以更新它。而且,当视图模型更新值时,视图也不会更新

要解决这个问题,只需不设置在代码背后有绑定的属性即可


与其在代码隐藏中处理button事件并更新视图,不如让button命令绑定到视图模型并更新视图模型中的FolderOrFileName。

只是好奇:我不知道[CallerMemberName]这个短语。这是vs版本>2010中的某个神奇编译器喧嚣吗?@Udontknow它是在.NET 4.5中引入的,基本上在编译时传递调用成员的名称。因此,它非常适合实现INPC。你看,只是好奇:我不知道[CallerMemberName]这个短语。这是vs版本>2010中的某个神奇编译器喧嚣吗?@Udontknow它是在.NET 4.5中引入的,基本上在编译时传递调用成员的名称。因此,它非常适合实现INPC。请参阅。文本框的默认绑定模式是双向的。自从我使用WPF以来已经有一段时间了-虽然我通常会发现指定模式更易于阅读。文本框的默认绑定模式是双向的。自从使用WPF以来已经有一段时间了-虽然我通常会发现指定模式更易于阅读。工作非常出色!!谢谢。工作很有魅力!!谢谢
<Button x:Name="ButtonRun" Content="Run" Command="{Binding ChangeFileName}" Width="200" Height="100" Margin="10"></Button>