Search code examples
wpfxamlbindingicommand

WPF: ICommand, open a txt file in textbox


I have a little problem here , I have to open (read) a text file in a basic WPF notepad kind thing , but i have to do with ICommand interface. The problem is that when i chose the txt file i want to open , nothings happen, I just see an empty notepad. There is any solution for this? Here is the code:

    public class OpenCommand : ICommand
{

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;


    public void Execute(object parameter)
    {
        OpenFileDialog op = new OpenFileDialog();

        op.Filter = "textfile|*.txt";
        op.DefaultExt = "txt";
        if(op.ShowDialog() == true)
        {

            File.ReadAllText(op.FileName);

        }

    }
}

Maybe the bindig is not i really don't know at this point.

                <MenuItem Header="File" >
                <MenuItem Header="New"/>
                <MenuItem Header="Open..." Command="{Binding MyOpenCommand}" CommandParameter="{Binding ElementName=textbox2, Path=Text}"/>
                <MenuItem Header="Save..." Command="{Binding MySaveCommand}" CommandParameter="{Binding ElementName=textbox2, Path=Text}"/>
                <Separator/>
                <MenuItem Header="Exit..." Command="{Binding MyExitCommand}"/>

            </MenuItem>

There is the binding, i want the see the file in the "textbox2"

<TextBox x:Name="textbox2" DockPanel.Dock="Left" 
             Grid.IsSharedSizeScope="True"
             AcceptsReturn="True"/> 

Solution

  • You have to bind the TextBox to the content of the text file.

    The following example uses the reusable RelayCommand which accepts a delegate. This makes passing of the result to the binding source more elegant.

    ViewModel.cs

    public class ViewModel : INotifyPropertyChanged
    {
      public ICommand OpenCommand => new RelayCommand(ExecuteOpemFile);
      public ICommand ExitCommand => new RelayCommand(param => Application.Current.MainWindow.Close());
    
      private string textFileContent;   
      public string TextFileContent
      {
        get => this.textFileContent;
        set 
        { 
          this.textFileContent= value; 
          OnPropertyChanged();
        }
      }
    
      public ExecuteOpemFile(object commandParameter)
      {
        OpenFileDialog op = new OpenFileDialog();
        op.Filter = "textfile|*.txt";
        op.DefaultExt = "txt";
    
        if(op.ShowDialog() == true)
        {
          this.TextFileContent = File.ReadAllText(op.FileName);
        }
      }
    
      public event PropertyChangedEventHandler PropertyChanged;
      protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
      {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
      }
    }
    

    RelayCommand.cs
    Implementation copied from Microsoft Docs: Relaying Command Logic.

    public class RelayCommand : ICommand
    {
      #region Fields
    
      readonly Action<object> _execute;
      readonly Predicate<object> _canExecute;
    
      #endregion // Fields 
    
      #region Constructors
    
      public RelayCommand(Action<object> execute) : this(execute, null)
      {
      }
    
      public RelayCommand(Action<object> execute, Predicate<object> canExecute)
      {
        if (execute == null)
          throw new ArgumentNullException("execute");
        _execute = execute;
        _canExecute = canExecute;
      }
    
      #endregion // Constructors 
    
      #region ICommand Members
    
      [DebuggerStepThrough]
      public bool CanExecute(object parameter)
      {
        return _canExecute == null ? true : _canExecute(parameter);
      }
    
      public event EventHandler CanExecuteChanged
      {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
      }
    
      public void Execute(object parameter)
      {
        _execute(parameter);
      }
    
      #endregion // ICommand Members 
    }
    

    MainWindow.xaml

    <Window>
      <Window.DataContext>
        <ViewModel />
      </Window.DataContext>
    
      <StackPanel>
        <Menu>
          <MenuItem Command="{Binding OpenCommand}" />
          <MenuItem Command="{Binding ExitCommand}" />
        </Menu>
    
        <TextBox Text="{Binding TextFileContent}" />
    </Window>