Hi,@_ ati . Welcome Microsoft Q&A.
For creating NotePad application in wpf project, you could refer to the code below.
Project structure:
MainWindow.xaml:
<Window x:Class="NotePadDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NotePadDemo"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<DockPanel Margin="1">
<Menu DockPanel.Dock="Top">
<Menu.Items>
<MenuItem Header="File" DataContext="{Binding File}">
<MenuItem Header="New" Command="{Binding NewCommand}"/>
<MenuItem Header="Open" Command="{Binding OpenCommand}"/>
<MenuItem Header="Save" Command="{Binding SaveCommand}"/>
<MenuItem Header="Save as..." Command="{Binding SaveAsCommand}"/>
</MenuItem>
<MenuItem Header="Format" DataContext="{Binding Editor}">
<MenuItem Header="Format" Command="{Binding FormatCommand}"/>
<MenuItem Header="Word wrap" Command="{Binding WrapCommand}"/>
</MenuItem>
<MenuItem Header="Help" DataContext="{Binding Help}">
<MenuItem Header="About" Command="{Binding HelpCommand}"/>
</MenuItem>
</Menu.Items>
</Menu>
<DockPanel>
<TextBlock DockPanel.Dock="Bottom" DataContext="{Binding File.Document}" Text="{Binding FilePath}"/>
<TextBox DockPanel.Dock="Top" VerticalScrollBarVisibility="Visible" DataContext="{Binding Editor}"
FontFamily="{Binding Format.Family}" FontSize="{Binding Format.Size}"
FontStyle="{Binding Format.Style}" FontWeight="{Binding Format.Weight}"
TextWrapping="{Binding Format.Wrap}" AcceptsReturn="True" AcceptsTab="True"
Text="{Binding Document.Text,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
</DockPanel>
</DockPanel>
</Window>
FontDialog:
<Window x:Class="NotePadDemo.FontDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NotePadDemo"
xmlns:media="clr-namespace:System.Windows.Media;assembly=PresentationCore"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:win="clr-namespace:System.Windows;assembly=PresentationCore"
mc:Ignorable="d"
Title="FontDialog" Height="450" Width="800">
<Window.Resources>
<ObjectDataProvider x:Key="FontFamilyOptions" ObjectType="{x:Type media:Fonts}" MethodName="get_SystemFontFamilies"/>
<x:Array x:Key="FontSizeOptions" Type="sys:Double">
<sys:Double>12</sys:Double>
<sys:Double>18</sys:Double>
<sys:Double>26</sys:Double>
<sys:Double>36</sys:Double>
<sys:Double>72</sys:Double>
</x:Array>
<x:Array x:Key="FontWeightOptions" Type="win:FontWeight">
<win:FontWeight>Normal</win:FontWeight>
<win:FontWeight>Bold</win:FontWeight>
<win:FontWeight>ExtraBold</win:FontWeight>
</x:Array>
<x:Array x:Key="FontStyleOptions" Type="win:FontStyle">
<win:FontStyle>Normal</win:FontStyle>
<win:FontStyle>Italic</win:FontStyle>
<win:FontStyle>Oblique</win:FontStyle>
</x:Array>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<DockPanel >
<TextBlock DockPanel.Dock="Top" >Font Family</TextBlock>
<ListBox ItemsSource="{Binding Source={StaticResource FontFamilyOptions}}"
SelectedItem="{Binding Family}" SelectedIndex="0">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding }" FontFamily="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
<DockPanel Grid.Row="0" Grid.Column="1">
<TextBlock DockPanel.Dock="Top"> Font Size</TextBlock>
<ListBox ItemsSource="{Binding Source={StaticResource FontSizeOptions}}"
SelectedItem="{Binding Size}" SelectedIndex="0"/>
</DockPanel>
<StackPanel Grid.Column="0" Grid.Row="1">
<TextBlock>Font Styles</TextBlock>
<ComboBox ItemsSource="{Binding Source={StaticResource FontStyleOptions}}"
SelectedItem="{Binding Style}" SelectedIndex="0"/>
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="1">
<TextBlock>Font Weight</TextBlock>
<ComboBox ItemsSource="{Binding Source={StaticResource FontWeightOptions}}"
SelectedItem="{Binding Weight}" SelectedIndex="0"/>
</StackPanel>
</Grid>
</Window>
Codebehind:
using Microsoft.Win32;
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
namespace NotePadDemo
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public class BaseModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] String propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class DocumentModel: BaseModel
{
private string text;
public string Text
{
get { return text; }
set
{
text = value;
NotifyPropertyChanged("Text");
}
}
private string filePath;
public string FilePath
{
get { return filePath; }
set
{
filePath = value;
NotifyPropertyChanged("FilePath");
}
}
private string fileName;
public string FileName
{
get { return fileName; }
set
{
fileName = value;
NotifyPropertyChanged("FileName");
}
}
public bool isEmpty
{
get
{
if (string.IsNullOrEmpty(FileName) || string.IsNullOrEmpty(FilePath))
return true;
return false;
}
}
}
public class FormatModel : BaseModel
{
private FontStyle style;
public FontStyle Style
{
get { return style; }
set
{
style = value;
NotifyPropertyChanged("Style");
}
}
private FontWeight weight;
public FontWeight Weight
{
get { return weight; }
set
{
weight = value;
NotifyPropertyChanged("Weight");
}
}
private FontFamily? family;
public FontFamily? Family
{
get { return family; }
set
{
family = value;
NotifyPropertyChanged("Family");
}
}
private TextWrapping wrap;
public TextWrapping Wrap
{
get { return wrap; }
set
{
wrap = value;
NotifyPropertyChanged("Wrap");
IsWrapped = value == TextWrapping.Wrap ? true : false;
}
}
private bool isWrapped;
public bool IsWrapped
{
get { return isWrapped; }
set
{
isWrapped = value;
NotifyPropertyChanged("IsWrapped");
}
}
private double size;
public double Size
{
get { return size; }
set
{
size = value;
NotifyPropertyChanged("Size");
}
}
}
public class MainViewModel
{
private DocumentModel document;
public EditorViewMode Editor { get; set; }
public FileViewModel File { get; set; }
public HelpViewModel Help { get; set; }
public MainViewModel()
{
document = new DocumentModel();
Editor = new EditorViewMode(document);
File = new FileViewModel(document);
Help = new HelpViewModel();
}
}
public class HelpViewModel : BaseModel
{
public ICommand HelpCommand { get; }
public HelpViewModel()
{
HelpCommand = new RelayCommand(DisplayAbout);
}
private void DisplayAbout()
{
//about
}
}
public class FileViewModel
{
public DocumentModel Document { get; private set; }
public ICommand NewCommand { get; }
public ICommand SaveCommand { get; }
public ICommand SaveAsCommand { get; }
public ICommand OpenCommand { get; }
public FileViewModel( DocumentModel document)
{
Document = document;
NewCommand = new RelayCommand(NewFile);
SaveCommand = new RelayCommand(SaveFile);
SaveAsCommand = new RelayCommand(SaveFileAs);
OpenCommand = new RelayCommand(OpenFile);
}
public void NewFile()
{
Document.FileName = string.Empty;
Document.FilePath = string.Empty;
Document.Text = string.Empty;
}
private void SaveFile()
{
File.WriteAllText(Document.FilePath, Document.Text);
}
private void SaveFileAs()
{
var saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Text File (*.txt)|*.txt";
if (saveFileDialog.ShowDialog() == true)
{
DockFile(saveFileDialog);
File.WriteAllText(saveFileDialog.FileName, Document.Text);
}
}
private void OpenFile()
{
var openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == true)
{
DockFile(openFileDialog);
Document.Text=File.ReadAllText(openFileDialog.FileName);
}
}
private void DockFile<T>(T dialog) where T :FileDialog
{
Document.FilePath = dialog.FileName;
Document.FileName = dialog.SafeFileName;
}
}
public class EditorViewMode
{
public ICommand FormatCommand { get; }
public ICommand WrapCommand { get; }
public FormatModel Format { get; set; }
public DocumentModel Document { get; set; }
public EditorViewMode(DocumentModel document)
{
Document = document;
Format = new FormatModel();
FormatCommand = new RelayCommand(OnpenStyleDialog);
WrapCommand = new RelayCommand(ToggleWrap);
}
private void OnpenStyleDialog()
{
var fontDialog = new FontDialog();
fontDialog.DataContext = Format;
fontDialog.ShowDialog();
}
private void ToggleWrap()
{
if (Format.Wrap == TextWrapping.Wrap)
Format.Wrap = TextWrapping.NoWrap;
else
Format.Wrap = TextWrapping.Wrap;
}
}
public class RelayCommand : ICommand
{
readonly Action _execute;
readonly Func<bool> _canExecute;
public RelayCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
throw new NullReferenceException("execute");
_execute = execute;
_canExecute = canExecute;
}
public RelayCommand(Action execute) : this(execute, null)
{
}
public event EventHandler? CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object? parameter)
{
return _canExecute == null ? true : _canExecute();
}
public void Execute(object? parameter)
{
_execute.Invoke();
}
}
}
The result:
Update:
Modify SaveFile() as follows:
private void SaveFile()
{
if (Document.FilePath == null)
{
var saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Text File (*.txt)|*.txt";
if (saveFileDialog.ShowDialog() == true)
{
DockFile(saveFileDialog);
File.WriteAllText(saveFileDialog.FileName, Document.Text);
}
}
else
{
File.WriteAllText(Document.FilePath, Document.Text);
}
}
If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.