c# - Load rtf in bindable RichTexBox mvvm wpf -
i'm new mvvm , load rtf file in richtextbox using mvvm, text doesn't seem display in richtextbox. looks richtextbox pretty complex deal when trying place commands in viewmodel. i'm not sure go wrong.
viewmodel
flowdocument _script; public flowdocument script { { 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(); } } }
the 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" />
the 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 xaml 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 document richtextbox.document = doc; // when document changes update 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())); } }; } }); }
and model
flowdocument _script; public flowdocument script // name property { { return _script; } set { _script = value; notifypropertychanged("script"); } }
i tried fill in gaps in sample code above, dependency property never triggered.
instead, got richtextbox populate changing xaml slightly:
<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>
there button bound openfilecommand
, property on viewmodel. passes richtextbox parameter command itself. i've moved loadscript()
method viewmodel 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 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; } }
Comments
Post a Comment