2015-06-13 16 views
5

Sono nuovo di mvvm e vorrei caricare un file rtf in un RichTextBox usando mvvm, ma il testo non sembra essere visualizzato nel mio richtextbox. Sembra che RichTextBox sia piuttosto complesso da gestire quando si tenta di posizionare i comandi nel ViewModel. Non sono sicuro di dove vado storto.Carica rtf in 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(); 
      } 
     } 
    } 

la vista

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" 
     /> 

il 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())); 
        } 
       }; 
      } 
     }); 
} 

e il modello

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

questo ti aiuta in qualche modo? http://www.codeproject.com/Articles/137209/Binding-and-styling-text-to-a-RichTextBox-in-WPF – niksofteng

+0

Il tuo metodo 'LoadScript' nel ViewModel viene sicuramente chiamato? –

risposta

1

Ho provato a riempire gli spazi vuoti nel codice di esempio sopra, ma la proprietà di dipendenza non viene mai attivata.

Invece, ho avuto la RichTextBox per popolare modificando leggermente la XAML:

<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> 

C'è un pulsante legato al OpenFileCommand, che è una proprietà sul ViewModel. Passa il RichTextBox come parametro al comando stesso. Ho spostato il metodo LoadScript() da ViewModel al comando.

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

Ho giocato con questo un po 'di più durante il fine settimana. Il tuo RichTextBoxHelper non viene chiamato, perché i tipi sono errati. Se viene modificato in questo modo:

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; 
      } 
     }); 
} 

Quindi viene colpito e imposta correttamente la proprietà del documento RichTextBox.