在可绑定的RichTexBox mvvm wpf中加载rtf

时间:2015-06-13 17:09:00

标签: c# wpf mvvm binding richtextbox

我是mvvm的新用户,我想使用mvvm在RichTextBox中加载rtf文件,但文本似乎不会显示在我的richtextbox中。在尝试将命令放入ViewModel时,看起来RichTextBox非常复杂。我不知道哪里出错了。

视图模型

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

视图

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

和模型

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

2 个答案:

答案 0 :(得分:1)

我试图填写上面示例代码中的空白,但永远不会触发您的依赖项属性。

相反,我通过稍微更改XAML来填充RichTextBox:

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

有一个绑定到OpenFileCommand的按钮,它是ViewModel上的一个属性。它将RichTextBox作为参数传递给Command本身。我已将LoadScript()方法从ViewModel移动到命令。

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 :(得分:1)

周末我在这玩了一点。您的RichTextBoxHelper未被调用,因为类型错误。如果将其修改为如下所示:

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

然后它被点击,并正确设置RichTextBox Document属性。