2015-06-13 13 views
5

Jestem nowy w mvvm i chciałbym załadować plik rtf w RichTextBox za pomocą mvvm, ale tekst nie wyświetla się w moim richtextbox. Wygląda na to, że RichTextBox jest dość skomplikowany, aby poradzić sobie z próbą umieszczenia poleceń w ViewModel. Nie jestem pewien, gdzie popełniam błąd.Załaduj plik rtf w bindable RichTexBox mvvm wpf

ViewModel

FlowDocument _script; 
public FlowDocument Script 
    { 
     get { return _script; } 
     set { _script = value; RaisePropertyChanged("Script"); } 
    } 
. 
. 
. 
private void LoadScript() 
    { 
     openFile.InitialDirectory = "C:\\"; 

     if (openFile.ShowDialog() == true) 
     { 
      string originalfilename = System.IO.Path.GetFullPath(openFile.FileName); 

      if (openFile.CheckFileExists) 
      { 
       Script = new FlowDocument(); 
       TextRange range = new TextRange(Script.ContentStart, Script.ContentEnd); 
       FileStream fStream = new FileStream(originalfilename, System.IO.FileMode.OpenOrCreate); 
       range.Load(fStream, DataFormats.Rtf); 
       fStream.Close(); 
      } 
     } 
    } 

View

DataContext="{Binding ScriptBreakdownViewModel, Source={StaticResource Locator}}"> 

<Grid> 
    <RichTextBox 
     Local:RichTextBoxHelper.DocumentRtf="{Binding Script}" 
     x:Name="rtfMain" 
     HorizontalAlignment="Left" 
     Width="673" 
     VerticalScrollBarVisibility="Visible" 
     Margin="0,59,0,10.4" 
     /> 

RichTextBoxHelper

public class RichTextBoxHelper : DependencyObject 
{ 
    public static string GetDocumentRtf(DependencyObject obj) 
    { 
     return (string)obj.GetValue(DocumentRtfProperty); 
    } 
    public static void SetDocumentRtf(DependencyObject obj, string value) 
    { 
     obj.SetValue(DocumentRtfProperty, value); 
    } 
    public static readonly DependencyProperty DocumentRtfProperty = 
     DependencyProperty.RegisterAttached(
     "DocumentRtf", 
     typeof(string), 
     typeof(RichTextBoxHelper), 
     new FrameworkPropertyMetadata 
     { 
      BindsTwoWayByDefault = true, 
      PropertyChangedCallback = (obj, e) => 
      { 
       var richTextBox = (RichTextBox)obj; 

       // Parse the XAML to a document (or use XamlReader.Parse()) 
       var Rtf = GetDocumentRtf(richTextBox); 
       var doc = new FlowDocument(); 
       var range = new TextRange(doc.ContentStart, doc.ContentEnd); 

       range.Load(new MemoryStream(Encoding.UTF8.GetBytes(Rtf)), 
        DataFormats.Rtf); 

       // Set the document 
       richTextBox.Document = doc; 

       // When the document changes update the source 
       range.Changed += (obj2, e2) => 
       { 
        if (richTextBox.Document == doc) 
        { 
         MemoryStream buffer = new MemoryStream(); 
         range.Save(buffer, DataFormats.Rtf); 
         SetDocumentRtf(richTextBox, 
          Encoding.UTF8.GetString(buffer.ToArray())); 
        } 
       }; 
      } 
     }); 
} 

a model

FlowDocument _script; 
    public FlowDocument Script // the Name property 
    { 
     get { return _script; } 
     set { _script = value; NotifyPropertyChanged("Script"); } 
    } 
+0

to ci pomaga w jakikolwiek sposób? http://www.codeproject.com/Articles/137209/Binding-and-styling-text-to-a-RichTextBox-in-WPF – niksofteng

+0

Czy twoja metoda "LoadScript" w ViewModel na pewno jest wywoływana? –

Odpowiedz

1

Próbowałem wypełnić luki w kodzie przykładowym powyżej, ale twoja własność zależności nigdy nie jest wyzwalana.

Zamiast tego mam RichTextBox do wypełnienia przez zmianę XAML nieznacznie:

<Button Height="30" Width="70" VerticalAlignment="Top" Command="{Binding OpenFileCommand}" CommandParameter="{Binding ElementName=myRichTextBox}">Load</Button> 
    <RichTextBox Name="myRichTextBox" 
     HorizontalAlignment="Left" 
     Width="673" 
     VerticalScrollBarVisibility="Visible" 
     Margin="0,59,0,10.4"></RichTextBox> 

znajduje się przycisk związany z OpenFileCommand, która jest właściwością w ViewModel. Przekazuje RichTextBox jako parametr do samego polecenia. Przenieśliłem metodę LoadScript() z ViewModel do Command.

public class OpenFileCommand : ICommand 
{ 
    private OpenFileDialog openFile = new OpenFileDialog(); 

    public bool CanExecute(object parameter) 
    { 
     return true; 
    } 

    public void Execute(object parameter) 
    { 
     var rtf = parameter as RichTextBox; 
     rtf.Document = LoadScript(); 
    } 

    public event EventHandler CanExecuteChanged; 

    private FlowDocument LoadScript() 
    { 
     openFile.InitialDirectory = "C:\\"; 

     if (openFile.ShowDialog() == true) 
     { 
      string originalfilename = System.IO.Path.GetFullPath(openFile.FileName); 

      if (openFile.CheckFileExists) 
      { 
       var script = new FlowDocument(); 
       TextRange range = new TextRange(script.ContentStart, script.ContentEnd); 
       FileStream fStream = new FileStream(originalfilename, System.IO.FileMode.OpenOrCreate); 
       range.Load(fStream, DataFormats.Rtf); 
       fStream.Close(); 
       return script; 
      } 
     } 

     return null; 
    } 
} 
1

Grałem z tym trochę więcej w weekend. Twój RichTextBoxHelper nie jest wywoływany, ponieważ typy są błędne. Jeśli zostanie zmodyfikowany w następujący sposób:

public class RichTextBoxHelper : DependencyObject 
{ 
    public static FlowDocument GetDocumentRtf(DependencyObject obj) 
    { 
     return (FlowDocument)obj.GetValue(DocumentRtfProperty); 
    } 
    public static void SetDocumentRtf(DependencyObject obj, FlowDocument value) 
    { 
     obj.SetValue(DocumentRtfProperty, value); 
    } 
    public static readonly DependencyProperty DocumentRtfProperty = 
     DependencyProperty.RegisterAttached(
     "DocumentRtf", 
     typeof(FlowDocument), 
     typeof(RichTextBoxHelper), 
     new FrameworkPropertyMetadata 
     { 
      BindsTwoWayByDefault = true, 
      PropertyChangedCallback = (obj, e) => 
      { 
       var richTextBox = (RichTextBox)obj; 
       richTextBox.Document = e.NewValue as FlowDocument; 
      } 
     }); 
} 

Następnie zostaje trafiony i prawidłowo ustawia właściwość dokumentu RichTextBox.