I am writing an academic application on WPF, in which there are two forms: the main one, in which the DataGrid is located and the form for adding / editing a record with the Yes and No buttons. enter image description here

In the form, when adding a note, the text is missing. Accordingly, I need to fill in the fields and press the "Yes" key, after which the data will be recorded. When editing, I display the text of the selected DataGrid in the form fields.

enter image description here

But when I click the "Yes" button, I can’t correctly make a check. When editing, instead of replacing adds a new position.

Part of XAML:

<TabItem x:Name="notesTab"> <TabItem.Header> <StackPanel Orientation="Horizontal"> <TextBlock Margin="3">Заметки</TextBlock> </StackPanel> </TabItem.Header> <TabItem.Content> <DataGrid Grid.Column="0" x:Name="ListOfNotes" AlternatingRowBackground ="LightGreen" RowBackground ="Green" Background="White" Margin="0,20,20,0" Loaded="grid_Loaded" IsReadOnly="True" BorderBrush="Black" Foreground="Black" OpacityMask="Black" SelectionChanged="ListOfNotes_SelectionChanged" LoadingRow="ListOfNotes_LoadingRow" SelectionMode="Single" SelectionUnit="FullRow"> <DataGrid.ContextMenu> <ContextMenu> <MenuItem Header="Добавить" Click="addNote_Click"></MenuItem> <MenuItem Header="Редактировать" Click="EditMenuItem_Click"></MenuItem> <MenuItem Command="Copy" Header="Копировать"></MenuItem> <MenuItem Header="Удалить" Click="MenuItem_Click"></MenuItem> <MenuItem Header="Удалить все" Click="DeleteAllMenuItem_Click"></MenuItem> </ContextMenu> </DataGrid.ContextMenu> <DataGrid.Effect> <BlurEffect Radius="10" x:Name="blur"/> </DataGrid.Effect> <DataGrid.Triggers> <EventTrigger RoutedEvent="UIElement.MouseEnter"> <BeginStoryboard> <Storyboard> <DoubleAnimation To="0" Duration="0:0:0.3" Storyboard.TargetName="blur" Storyboard.TargetProperty="Radius"/> </Storyboard> </BeginStoryboard> </EventTrigger> <EventTrigger RoutedEvent="UIElement.MouseLeave"> <BeginStoryboard> <Storyboard> <DoubleAnimation To="10" Duration="0:0:0.5" Storyboard.TargetName="blur" Storyboard.TargetProperty="Radius"/> </Storyboard> </BeginStoryboard> </EventTrigger> </DataGrid.Triggers> </DataGrid> </TabItem.Content> </TabItem> </TabControl> </StackPanel> 

The code for the entry handler to edit the main screen (header and content form text fields):

  int selectedColumn = 0; bool selectTrue = false; private void ListOfNotes_SelectionChanged(object sender, SelectionChangedEventArgs e) { selectedColumn = ListOfNotes.CurrentCell.Column.DisplayIndex; selectTrue = true; } private void EditMenuItem_Click(object sender, RoutedEventArgs e) { if (selectTrue) { NotesWindow notesWindow = new NotesWindow(); var selectedCell = ListOfNotes.SelectedCells[selectedColumn]; var cellContent = selectedCell.Column.GetCellContent(selectedCell.Item); NotesData notesData = new NotesData(); for (int i = 0; i < Constants.DATAGRID_SIZE; i++) { selectedCell = ListOfNotes.SelectedCells[i]; cellContent = selectedCell.Column.GetCellContent(selectedCell.Item); switch (i) { case 0: notesData.Id = Guid.Parse((cellContent as TextBlock).Text); test = notesData.Id; break; case 1: notesWindow.header.Text = (cellContent as TextBlock).Text; break; case 2: notesWindow.content.AppendText((cellContent as TextBlock).Text); break; } } notesWindow.Show(); } else ShowError(UserNotifications.NO_ENTRY_SELECTED); } 

Code in the form to fill / edit.`

  private void confirm_Click(object sender, RoutedEventArgs e) { try { if (notesData.Id == Guid.Empty) { if (string.IsNullOrWhiteSpace(header.Text) && string.IsNullOrWhiteSpace(GetStringFromRtb(content))) { ShowError(UserNotifications.FILL_ALL_FIELDS); } else { notesData.Id = Guid.NewGuid(); notesData.Header = header.Text; notesData.Content = GetStringFromRtb(content); factory.CreateNotesFactory().Add(notesData); this.Close(); } } if (notesData.Id == MainWindow.test) { //notesData.Id = Guid.Parse("689f5ab7-f779-4df3-bece-1aaaa64f8ddf"); // Проверка; notesData.Id = MainWindow.test; notesData.Header = header.Text; notesData.Content = GetStringFromRtb(content); factory.CreateNotesFactory().Edit(notesData); this.Close(); } } catch (Exception err) { ShowError(err, UserNotifications.ERROR); } } 
  • 2
    Why not MVVM? Not surprisingly, you're drowning in UI-dependent code. You have all the business logic in onclick. - VladD
  • 2
    Read about MVVM INotifyPropertyChange and ListCollectionView. and you will be happy. - ParanoidPanda
  • As already written above, you just use the wrong approach, try to separate the logic from the presentation - user227049
  • Perhaps the advice will seem a bit strange, but it may be a good way to understand how to work with WPF more or less correctly, to rewrite the application with F# =) In any case, I started this way - user227049
  • Thanks for the advice, I will go to teach. In this situation, you can think of something other than the MVVM pattern? - JDo

1 answer 1

In general, I just made a check. What would work. I will continue to rewrite using MVVM.

  private void confirm_Click(object sender, RoutedEventArgs e) { try { if (MainWindow.test != Guid.Empty) { //notesData.Id = Guid.Parse("689f5ab7-f779-4df3-bece-1aaaa64f8ddf"); // Проверка; Dispatcher.Invoke(new Action(delegate { notesData.Id = MainWindow.test; notesData.Header = header.Text; notesData.Content = GetStringFromRtb(content); //factory.CreateNotesFactory().Edit(notesData); notesService.Edit(notesData); })); this.Close(); } else //if (notesData.Id == Guid.Empty && MainWindow.test == Guid.Empty) { if (string.IsNullOrWhiteSpace(header.Text) && string.IsNullOrWhiteSpace(GetStringFromRtb(content))) { ShowError(UserNotifications.FILL_ALL_FIELDS); } else { Dispatcher.Invoke(new Action(delegate { notesData.Id = Guid.NewGuid(); notesData.Time = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalHours; notesData.Header = header.Text; notesData.Content = GetStringFromRtb(content); //factory.CreateNotesFactory().Add(notesData); notesService.Add(notesData); })); this.Close(); } } } catch (Exception err) { ShowError(err, UserNotifications.ERROR); } } 

It seems to work.