Hello
I am implementing a richtextbox on my WPF, using MVVM, but I found that is very problematic, could somebody help me with MVVMFY, I also find out that WPF is very troublesome to work with, especially when you make dependency properties and user controls. You have to rebuild every time, so it can be aware of changes, which is a pain.
Anyway,
As I mentioned earlier, I do not know how to work with MVVM and the rich textbox
My app is almost finished, but I want to get rid of all my code behind, and put it in my view model
This is the UI for the notes Page
<ToggleButton BorderBrush="Transparent"
Background="Transparent"
Name="SpeechBton"
FontSize="18"
Tag="0"
Click="SpeechBton_Click">
<TextBlock Text="Speech" />
</ToggleButton>
<ToggleButton Margin="20,0,0,0"
Name="boldBton"
FontSize="18"
Tag="1"
Click="SpeechBton_Click"
BorderBrush="Transparent"
Background="Transparent">
<TextBlock Text="B" />
</ToggleButton>
<ToggleButton Margin="20,0,0,0"
Name="italicBton"
FontSize="18"
Tag="2"
Click="SpeechBton_Click"
BorderBrush="Transparent"
Background="Transparent">
<TextBlock Text="I" />
</ToggleButton>
<ToggleButton Margin="20,0,0,0"
FontSize="18"
Name="UndelineBton"
Tag="3"
Click="SpeechBton_Click"
BorderBrush="Transparent"
Background="Transparent">
<TextBlock Text="U" />
</ToggleButton>
<Fluent:ComboBox Width="100"
x:Name="FontsComboBox"
ItemsSource="{Binding fonts, Mode=TwoWay}"
SelectionChanged="FontsComboBox_SelectionChanged"
IsEditable="False" />
<Fluent:ComboBox Width="50"
ItemsSource="{Binding FontSizes, Mode=TwoWay}"
x:Name="SizeConboBox"
SelectionChanged="SizeConboBox_SelectionChanged" />
</StackPanel>
</ToolBar>
</ToolBarTray>
<RichTextBox Grid.Row="1"
x:Name="NoteContent"
TextChanged="NoteContent_TextChanged"
SelectionChanged="NoteContent_SelectionChanged"
Foreground="Black"/>
<StatusBar Grid.Row="2">
<TextBlock x:Name="NumOfCharacters" />
</StatusBar>
My VM for notes
public ICommand ExitCommand { get; set; }
public ICommand NewNotebookCommand { get; set; }
public ICommand NewNoteCommand { get; set; }
public ICommand RenameCommand { get; set; }
public List<int> FontSizes { get; set; }
public IOrderedEnumerable<FontFamily> fonts { get; set; }
public ObservableCollection<Notebook> Notebooks { get; set; }
public ObservableCollection<Note> Notes { get; set; }
private Notebook _SelectedNoteBook;
public Notebook SelectedNoteBook {
get { return _SelectedNoteBook; }
set {
if (_SelectedNoteBook != value) {
_SelectedNoteBook = value;
RaisePropertyChanged();
GetNotes();
}
}
}
private bool _IsVisible;
public bool IsVisible {
get { return _IsVisible; }
set {
if (_IsVisible != value) {
_IsVisible = value;
RaisePropertyChanged();
}
}
}
public NotesWindowVM() {
IsVisible = false;
Notes = new ObservableCollection<Note>();
Notebooks = new ObservableCollection<Notebook>();
fonts = Fonts.SystemFontFamilies.OrderBy(f => f.Source);
FontSizes = new List<int>();
for (int i = 7; i < 72; i++) {
FontSizes.Add(i);
}
RenameCommand = new Command(() => {
IsVisible = true;
});
ExitCommand = new Command(() => {
Application.Current.Shutdown();
});
NewNotebookCommand = new Command(() => {
CreateNewNotebook();
});
NewNoteCommand = new HelperCommand {
ExecuteDelegate = x => CreateNewNote(SelectedNoteBook.Id),
CanExecuteDelegate = x => SelectedNoteBook != null
};
GetNoteBooks();
}
private void CreateNewNote(int NotebookId) {
Note note = new() {
NotebookId = NotebookId,
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now,
Title = "New Note"
};
Database.Insert(note);
GetNotes();
}
private void CreateNewNotebook() {
Notebook notebook = new() { Name = $"Notebook" };
Database.Insert(notebook);
GetNoteBooks();
}
private void GetNoteBooks() {
var notebooks = Database.Read<Notebook>();
Notebooks.Clear();
foreach (var item in notebooks) {
Notebooks.Add(item);
}
}
private void GetNotes() {
if (SelectedNoteBook != null) {
var notes = Database.Read<Note>().Where(
n => n.NotebookId == SelectedNoteBook.Id)
.ToList();
Notes.Clear();
foreach (var item in notes) {
Notes.Add(item);
}
}
}
}
and I want to get rid of all this and implemented it on my VM
code-behind for notes
public NotesWindow() {
InitializeComponent();
var speechRecognizer = SpeechConfig.FromSubscription(key, region);
var audioConfig = AudioConfig.FromDefaultMicrophoneInput();
recog = new SpeechRecognizer(speechRecognizer, audioConfig);
recog.Recognized += SpeechRecognizer_Recognized;
}
private async void SpeechRecognizer_Recognized(object sender, SpeechRecognitionEventArgs e) {
if (e.Result.Reason == ResultReason.RecognizedSpeech) {
await Dispatcher.InvokeAsync(() => NoteContent.AppendText($"{e.Result.Text}"));
}
}
private void NoteContent_TextChanged(object sender, TextChangedEventArgs e) {
FlowDocument doc = NoteContent.Document;
int count = new TextRange(doc.ContentStart, doc.ContentEnd).Text.Length;
NumOfCharacters.Text = $"Characters: {count}";
}
private async void SpeechBton_Click(object sender, RoutedEventArgs e) {
var toggle = sender as System.Windows.Controls.Primitives.ToggleButton;
switch (toggle.Tag) {
case "0":
if (!isRecognizing) {
await recog.StartContinuousRecognitionAsync();
isRecognizing = true;
SpeechBton.IsChecked = true;
} else {
await recog.StopContinuousRecognitionAsync();
isRecognizing = false;
SpeechBton.IsChecked = false;
}
break;
case "1":
bool isChecked = toggle.IsChecked ?? false;
if (isChecked) {
NoteContent.Selection.ApplyPropertyValue(FontWeightProperty, FontWeights.Bold);
} else {
NoteContent.Selection.ApplyPropertyValue(FontWeightProperty, FontWeights.Normal);
}
break;
case "2":
bool isEnable = toggle.IsChecked ?? false;
if (isEnable) {
NoteContent.Selection.ApplyPropertyValue(FontStyleProperty, FontStyles.Italic);
} else {
NoteContent.Selection.ApplyPropertyValue(FontStyleProperty, FontStyles.Normal);
}
break;
case "3":
bool isPressed = toggle.IsChecked ?? false;
if (isPressed) {
NoteContent.Selection.ApplyPropertyValue(Inline.TextDecorationsProperty, TextDecorations.Underline);
} else {
(NoteContent.Selection.GetPropertyValue(Inline.TextDecorationsProperty) as TextDecorationCollection)
.TryRemove(TextDecorations.Underline, out TextDecorationCollection decorations);
NoteContent.Selection.ApplyPropertyValue(Inline.TextDecorationsProperty, decorations);
}
break;
}
}
private void NoteContent_SelectionChanged(object sender, RoutedEventArgs e) {
var selectionFontWeight = NoteContent.Selection.GetPropertyValue(Inline.FontWeightProperty);
boldBton.IsChecked = (selectionFontWeight != DependencyProperty.UnsetValue)
&& selectionFontWeight.Equals(FontWeights.Bold);
var selectionFontStyle = NoteContent.Selection.GetPropertyValue(Inline.FontStyleProperty);
italicBton.IsChecked = (selectionFontStyle != DependencyProperty.UnsetValue)
&& selectionFontStyle.Equals(FontStyles.Italic);
var selectionFontDecoration = NoteContent.Selection.GetPropertyValue(Inline.TextDecorationsProperty);
UndelineBton.IsChecked = (selectionFontDecoration != DependencyProperty.UnsetValue)
&& selectionFontDecoration.Equals(TextDecorations.Underline);
FontsComboBox.SelectedItem = NoteContent.Selection.GetPropertyValue(FontFamilyProperty);
SizeConboBox.Text = (NoteContent.Selection.GetPropertyValue(FontSizeProperty)).ToString();
}
private void FontsComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
if (FontsComboBox.SelectedItem != null) {
NoteContent.Selection.ApplyPropertyValue(FontFamilyProperty, FontsComboBox.SelectedItem);
}
}
private void SizeConboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
NoteContent.Selection.ApplyPropertyValue(FontSizeProperty, SizeConboBox.Text);
}
}
}
