Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单击按钮时,如何将文本指定给从文件读取的文本块_C#_Wpf_Xaml_Mvvm - Fatal编程技术网

C# 单击按钮时,如何将文本指定给从文件读取的文本块

C# 单击按钮时,如何将文本指定给从文件读取的文本块,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我的应用程序必须从文件系统加载.txt文件,读取它并将其文本放入文本块,但我不知道如何将我的按钮连接到我的视图模型,以便绑定到其中某个属性的文本块显示此文本 让我们重复一下我希望我的应用程序执行的操作: 用户单击加载按钮,然后选择一个.txt文件 文件中的文本被指定给numberstring属性 文本块从numberstring属性加载此文本 我不知道如何让第二步起作用 XAML 视图模型 class numbersViewModel : INotifyPropertyChanged {

我的应用程序必须从文件系统加载
.txt
文件,读取它并将其文本放入
文本块
,但我不知道如何将我的
按钮
连接到我的视图模型,以便绑定到其中某个属性的文本块显示此文本

让我们重复一下我希望我的应用程序执行的操作:

  • 用户单击加载按钮,然后选择一个
    .txt
    文件
  • 文件中的文本被指定给
    numberstring
    属性
  • 文本块从
    numberstring
    属性加载此文本
  • 我不知道如何让第二步起作用

    XAML

    视图模型

    class numbersViewModel : INotifyPropertyChanged
    {
       public event PropertyChangedEventHandler PropertyChanged;
    
       private numbersModel _model;
    
       protected void RaisePropertyChanged(string propertyName)
       {
          PropertyChangedEventHandler evt = PropertyChanged;
          if (evt != null)
             evt(this, new PropertyChangedEventArgs(propertyName));
       }
       
       // iI want my text block to take the string from here
       public string NumbersString
       {
          get { return _model.numbersString; }
          set
          {
             if (value != _model.numbersString)
             {
                _model.numbersString = value;
                RaisePropertyChanged("numbers1");
             }
          }
       }
    }
    
    模型


    您在
    numberstring
    属性中引发了
    numbers1
    的属性更改事件,因此会触发对错误属性(甚至不存在)的更改,但这不会更新
    文本框

    将调用中的属性名称改编为
    RaisePropertyChanged
    。您可以使用而不是硬编码的
    字符串

    public string NumbersString
    {
       get { return _model.numbersString; }
       set
       {
          if (value != _model.numbersString)
          {
             _model.numbersString = value;
             RaisePropertyChanged(nameof(NumbersString));
          }
       }
    }
    
    由于您混合使用代码隐藏和MVVM,因此可以在事件处理程序中设置
    numberString
    属性,如下所示:

    public void load_Click(object sender, RoutedEventArgs e)
    {
       OpenFileDialog openFileDialog = new OpenFileDialog();
       if (openFileDialog.ShowDialog() == true)
          ((numbersViewModel)DataContext).NumbersString = File.ReadAllText(openFileDialog.FileName);
    }
    
    最后一点是,不要创建
    numbersViewModel
    的实例,也不要将其分配给
    numbersViewModel
    上的
    \u model
    属性。您可以在构造函数中执行此操作

    public numbersViewModel(numbersModel numbersModel)
    {
       _model = numbersModel;
    }
    
    使用命令的MVVM方法 您应该使用命令,而不是使用事件处理程序来单击按钮。您可以复制所需的
    RelayCommand
    类。首先,在
    numbersViewModel
    中创建一个
    ICommand
    属性

    public ICommand LoadFile { get; }
    
    RelayCommand
    实现
    ICommand
    接口,并将执行逻辑委托给在
    numbersViewModel的构造函数中创建时必须传递的方法:

    public numbersViewModel(numbersModel numbersModel)
    {
       _model = numbersModel;
       LoadFile = new RelayCommand(ExecuteLoadFile);
    }
    
    ExecuteLoadFile
    方法包含加载文件和读取文件文本的逻辑。实际上,这也违反了MVVM原则,因为此方法位于视图模型中,并且
    OpenFileDialog
    是一种视图类型。您可以将此部分提取到具有接口的服务中,这样视图模型就不知道其实现,但这超出了本问题的范围

    private void ExecuteLoadFile(object obj)
    {
       var openFileDialog = new OpenFileDialog();
       if (openFileDialog.ShowDialog().GetValueOrDefault())
          NumbersString = File.ReadAllText(openFileDialog.FileName);
    }
    
    最后,将按钮上的
    命令
    属性绑定到
    加载文件
    命令

    <Button Name="load" Background="Pink" Content="Load File" Command="{Binding LoadFile}"/>
    
    
    

    通过这些更改,您可以从
    主窗口中删除事件处理程序

    RaisePropertyChanged(“numbers1”)
    =>
    RaisePropertyChanged(“numberString”)
    在xaml后面的代码中,我应该把它放在哪里?只需修复
    PropertyChanged
    调用中的错误。关于button+MVVM,请参考以下内容:和。回答正确,非常简单,但违反了MVVM。
    ICommand
    用法如何?@aepot我已经更新了答案,加入了使用命令的方法。现在好多了:)
    public numbersViewModel(numbersModel numbersModel)
    {
       _model = numbersModel;
       LoadFile = new RelayCommand(ExecuteLoadFile);
    }
    
    private void ExecuteLoadFile(object obj)
    {
       var openFileDialog = new OpenFileDialog();
       if (openFileDialog.ShowDialog().GetValueOrDefault())
          NumbersString = File.ReadAllText(openFileDialog.FileName);
    }
    
    <Button Name="load" Background="Pink" Content="Load File" Command="{Binding LoadFile}"/>