1

Изучаю построение MVVM в wpf. Делаю тестовый проект для этого. Пока что мне трудно понять эту концепцию, и самое главное как работать с элементами не имея к ним доступа на прямую. Самое простое, не понятно как при такой структуре взять текст из RichTextBox и дальше что то с ним сделать. То есть проблема просто получить объект не имея к нему доступа.

Код:

MainWindow.xaml:

<Window x:Class="TextEditorNetFramework.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:TextEditorNetFramework.ViewModel"
        mc:Ignorable="d"
        xmlns:viewModels="clr-namespace:TextEditorNetFramework.ViewModel"
        Title="{Binding Title}" Height="700" Width="1200">
    <Window.DataContext>
        <local:MainVM/>
        <!-- Устанавливаем DataContext -->
    </Window.DataContext>
&lt;Grid Margin=&quot;7,3,0,0&quot;&gt;
    &lt;Menu DockPanel.Dock=&quot;Top&quot; Margin=&quot;-7,-3,7,645&quot;&gt;
        &lt;MenuItem Header=&quot;Файл&quot;&gt;
            &lt;MenuItem Header=&quot;Сохранить&quot;/&gt;
        &lt;/MenuItem&gt;
    &lt;/Menu&gt;

    &lt;TabControl Background=&quot;#2b4961&quot; Margin=&quot;-6,30,0,0&quot;&gt;
        &lt;TabItem Header=&quot;Main.txt&quot; BorderThickness=&quot;7&quot;  Width=&quot;130&quot; Margin=&quot;-3,-2,3,0&quot;&gt;
            &lt;RichTextBox Foreground=&quot;White&quot; x:Name=&quot;MainRichTextBox&quot; Background=&quot;#2b4961&quot; HorizontalScrollBarVisibility=&quot;Auto&quot; VerticalScrollBarVisibility=&quot;Auto&quot; BorderThickness=&quot;0&quot; BorderBrush=&quot;Black&quot; Height=&quot;627&quot; Margin=&quot;56,0,-4,0&quot; Padding=&quot;3&quot; FontFamily=&quot;Segoe UI&quot; FontSize=&quot;14&quot;&gt;
            &lt;/RichTextBox&gt;
        &lt;/TabItem&gt;
    &lt;/TabControl&gt;
    &lt;Grid x:Name=&quot;Test&quot; Margin=&quot;-8,53,1138,0&quot; Background=&quot;#2b4961&quot;/&gt;
    &lt;Line X1=&quot;100&quot; X2=&quot;100&quot; Y1=&quot;0&quot; Y2=&quot;1200&quot; Stroke=&quot;Black&quot;
 StrokeThickness=&quot;0.3&quot; Margin=&quot;-59,55,1083,-5&quot; RenderTransformOrigin=&quot;0.764,0.501&quot;/&gt;

&lt;/Grid&gt;

</Window>

MainVM.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using Prism.Mvvm;

namespace TextEditorNetFramework.ViewModel { public class MainVM : BindableBase { readonly Model.MainModel _model = new Model.MainModel(); public MainVM() { _model.PropertyChanged += (s, e) => { RaisePropertyChanged(e.PropertyName); }; } public string Title => _model.Title; } }

MainModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prism.Mvvm;

namespace TextEditorNetFramework.Model { public class MainModel : BindableBase { private readonly string _Title = "TextEditor Alpha v0.1"; public string Title => _Title; } }

В MainWindow.xaml.cs(По сути View) Понятное дело, ничего нет кроме инициализации.

И возвращаемся к сути, как мне банально получить объект моего RichTextBox(Да и вообще другие объекты) для дальнейшего извлечения текста и работы с ним вообще? Или на крайний случай просто сам текст получить. Возможно стоит как то перестроить мой код?

  • 2
    Все махинации с контролами делайте внутри кода окна, ViewModel просто связывает бизнес-логику и представление, если надо что-то из контрола получить - биндите к свойству из ViewModel – Aarnihauta Jul 14 '22 at 11:46
  • 3
    <local:MainVM/> - плохо, Margin="-7,-3,7,645" - ужасно! Научитесь позиционировать, а не двигать все в конструкторе. using Prism.Mvvm; - не стоит без понимания того, как все устроено, использовать сторонние библиотеки, которые вообще заставят вас иначе писать проект. RichTextBox - не очень удачный контрол для начала, советую пока обойтись простым TextBox. – EvgeniyZ Jul 14 '22 at 12:03
  • Спасибо, замечания учту. – whiteboy_ Jul 14 '22 at 13:17

1 Answers1

1

Подход MVVM призван разделить доступ к данным и визуальную часть.

Во View части будет находиться только ваша разметка. Визуальное представление, никаких манипуляций с контролами (в идеале) в коде быть не должно.

Ваша же ViewModel будет содержать сами данные, с которыми вы работаете (те же текстовые поля, числовые и прочие).

С помощью механизма Binding ваше View получает нотификации об изменении данных в вашей ViewModel. Например так:

class SimpleViewModel : INotifyPropertyChanged
{
  private string _title;
  public string Title
  {
      get { return _title; }
      set
      {
          _title = value;
          OnPropertyChanged("Title");
      }
  }

public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string prop) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(prop)); } }

Тогда в вашем View, к примеру:

<TextBox Text="{Binding Title}" />

Для более подробного разбора, предлагаю вам для начала ознакомиться с интерфейсом INotifyPropertyChanged, прежде чем использовать готовые библиотеки.