我正在尝试使用FlowDocument制作RichTextBox,以便可以在插入符号位置插入文本。我可以在文档末尾添加文本。我认为我的设置中缺少允许我的VM访问Flowocument的东西,或者我将其设置为错误。如果我在VM中创建FlowDocument并尝试将RichTextBox设置为它,则会收到错误消息MyEditor(RichTextBox)不存在。我可以使用ListBox中的AddItemBtn将文本添加到RichTextBox中,这样至少可以完成很多工作。
我的问题是“我应该如何设置RichTextBox/FlowDocument?
XAML代码
<Window x:Class="Scripter.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Scripter.ViewModels"
xmlns:wpftoolkit="clr-namespace:Xceed.Wpf.Toolkit;assembly=Xceed.Wpf.Toolkit"
Title="MainWindow" Height="350" Width="725">
<Grid HorizontalAlignment="Stretch">
<Grid HorizontalAlignment="Stretch" Height="72" Margin="10,14,0,0" VerticalAlignment="Top" Width="auto">
<WrapPanel HorizontalAlignment="Left" Height="50" Margin="10,0,0,0" VerticalAlignment="Top">
</WrapPanel>
<Button x:Name="OpenFilesBtn" Content="Open" HorizontalAlignment="Left" Margin="15,10,0,0" VerticalAlignment="Top" Width="75" Command="{Binding OpenFileBtn}"/>
<Button x:Name="SavefilesBtn" Content="Save" HorizontalAlignment="Left" Margin="104,10,0,0" VerticalAlignment="Top" Width="75" Command="{Binding SaveFileBtn}"/>
<TextBlock x:Name="OpenFile" Text="{Binding OpenFile,Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="15,37,0,0" VerticalAlignment="Top" Width="353"/>
<ComboBox x:Name="TipsBtn" SelectedIndex="0" ItemsSource="{Binding Path=Tabs, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Path=SelectedOption}" HorizontalAlignment="Left" Margin="538,10,0,0" VerticalAlignment="Top" Width="120"/>
<Button x:Name="AddItemBtn" Content="Add Item" HorizontalAlignment="Left" Margin="417,10,0,0" VerticalAlignment="Top" Width="100" Command="{Binding AddItemBtn}" CommandParameter="{Binding ElementName=AddItemList,Path=SelectedItem}"/>
</Grid>
<Grid Margin="10,100,10,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<RichTextBox Grid.Column="0" x:Name="MyEditor" SelectionChanged="MyEditor_SelectionChanged" ScrollViewer.VerticalScrollBarVisibility="Auto" Margin="0" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" IsDocumentEnabled="True" AcceptsTab="True" AcceptsReturn="True" >
<RichTextBox.Resources>
<Style TargetType="{x:Type Paragraph}">
<Setter Property="Margin" Value="0" ></Setter>
<Setter Property="FontSize" Value="15"></Setter>
</Style>
</RichTextBox.Resources>
<FlowDocument >
<Paragraph >
<Run Text="{Binding TestText}" ></Run>
</Paragraph>
</FlowDocument>
</RichTextBox>
<ListBox x:Name="AddItemList" Grid.Column="1" Width="Auto" Height="Auto" ItemsSource="{Binding Path=OptionsToChoose}" SelectedItem="ItemSelected">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="TextSelected" Text="{Binding Description}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
出现问题的VM代码
public ScripterViewModel()
{
ScripterModel scripterModel = new ScripterModel();
ObservableCollection<string> tabsChoice = new ObservableCollection<string>();
tabsChoice.Add("Tabs");
tabsChoice.Add("Buttons");
Tabs = tabsChoice;
this.OpenFileBtn = new DelegateCommand(chooseFile, canChooseFile).ObservesProperty(() => OpenFile);
this.SaveFileBtn = new DelegateCommand(saveFile, canSaveFile).ObservesProperty(() => SaveFile);
this.AddItemBtn = new DelegateCommand<Tabbed>(addItem);
FlowDocument flowDoc = new FlowDocument();
Paragraph p = new Paragraph(new Run("new paragraph"));
flowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 1")));
flowDoc.Blocks.Add(p);
//MyEditor = flowDoc;
}
public void MyEditor_SelectionChanged(object sender, RoutedEventArgs e)
{
// TextRange tempRange = new TextRange(MyEditor.Document.ContentStart, MyEditor.Selection.Start);
MessageBox.Show("Selection Changed");
}
private string _testText;
public string TestText
{
get
{
return _testText;
}
set
{
string _temp;
_temp = _testText + value;
SetProperty(ref _testText, value);
}
}
最佳答案
嘿,我是WPF和MVVM的新手,但我会尽力为您提供帮助。所以,如果我错了,不要怪我。
1.设置Window.DataContext
首先,您必须告诉View从何处获取数据。
可以通过将以下代码添加到View.xaml中来完成此操作:
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
但是请确保您的 namespace 变量(此处为“local”)指向您的ViewModels。xmlns:local="clr-namespace:Client.ViewModel"
这是前。指向我的ViewModel文件夹。2.定义一个OnPropertyChanged方法
您的 View 不知道您是否已修改变量。因此,您需要一种方法来通知您的 View 有关更改。
首先,为您的ViewModel实现
INotifyPropertyChanged
接口(interface)。public class MainViewModel : ViewModelBase, INotifyPropertyChanged
现在添加以下代码: public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
3.使用OnPropertyChanged因此,现在您有了一种方法来告诉View变量已更改,但是如何使用它呢?
为了向您解释这一点,我将使用您的FlowDocument flowDoc。
因此,让我们从定义
FlowDocument
设置开始:private FlowDocument _flowDoc;
现在让我们为flowDoc编写一个getter和setter方法: public FlowDocument FlowDoc
{
get
{
return _flowDoc;
}
set
{
_flowDoc = value;
}
}
现在是时候使用在 2中创建的OnPropertyChanged方法了。在 setter 部分,您想添加以下代码:
OnPropertyChanged("variable");
现在,您的结果应如下所示:public FlowDocument FlowDoc
{
get
{
return _flowDoc;
}
set
{
_flowDoc = value;
OnPropertyChanged("FlowDoc");
}
}
重要提示:请记住将其应用于所有变量!4.正确使用MVVM模式
在MVVM中,您有一个模型,一个 View 和一个 ViewModel 。
该模型用于您的数据,因此,如果可能的话,请勿在ViewModel中存储数据,而应将数据类用于ex。
您可以看看 this 和/或 this 。
正如我在一开始所说的那样,我对所有这些都是新手,但我希望它能对您有所帮助
你。随便问。
关于c# - MVVM从VM访问Richtextbox流文档,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44320188/