PropertyChanged + LostFocus with RichTextbox Attached Property

630 views
Skip to first unread message

Michael Sync

unread,
Apr 7, 2009, 6:06:03 AM4/7/09
to wpf-di...@googlegroups.com

Hello, 

I got the requirement that we need to support the binding and HTML text in WPF Rich Text so I started creating an attached properties for that. But I'm facing a few problems. As Microsoft has XamlToHTML converter, the conversion can be done very easily. But having a few problems with LostFocus and PropertyChanged.

 Problem #1:

 Let me started with LostFocus problem.  

My attached property is as below.  

public static class RichTextboxAssistant{

    public static readonly DependencyProperty BoundDocument =           DependencyProperty.RegisterAttached("BoundDocument", typeof(string), typeof(RichTextboxAssistant), new PropertyMetadata(OnBoundDocumentChanged));

    private static void OnBoundDocumentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){

            RichTextBox box = d as RichTextBox;

             if (box == null){

                return;

            }

 

            box.LostFocus -= HandleTextChanged;

 

 

            TextRange tr = new TextRange(box.Document.ContentStart,

                               box.Document.ContentEnd);

 

           

            string newXAML = (string)e.NewValue;

 

            MemoryStream xamlMemoryStream = new MemoryStream(Encoding.ASCII.GetBytes(newXAML));

            ParserContext pc = new ParserContext();

            pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");

            pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");

            FlowDocument doc = new FlowDocument();

            Section section = XamlReader.Load(xamlMemoryStream, pc) as Section;

            doc.Blocks.Add(section);

               

            box.Document = doc;

 

            box.LostFocus += HandleTextChanged;

        }

 

 

        private static void HandleTextChanged(object sender, RoutedEventArgs e)

        {

            RichTextBox box = sender as RichTextBox;

 

            TextRange tr = new TextRange(box.Document.ContentStart,

                               box.Document.ContentEnd);

 

            MemoryStream ms = new MemoryStream();

            tr.Save(ms, DataFormats.Xaml);

            string xamlText = ASCIIEncoding.Default.GetString(ms.ToArray());

 

            SetBoundDocument(box, xamlText);

        }

 

        public static string GetBoundDocument(DependencyObject dp)

        {

            return (string)dp.GetValue(BoundDocument);

        }

 

        public static void SetBoundDocument(DependencyObject dp, string value)

        {

            dp.SetValue(BoundDocument, value);

        }

    }

 

Usages

 

XAML

 

  <RichTextBox Name="mainRTB" AcceptsTab="True"

                     asis:RichTextboxAssistant.BoundDocument="{Binding Document}"

                         Height="150" />

 

I set the Document property like that and it’s working fine. 

Document = "<font color=\"red\">Michael" + new Random().Next().ToString() + " </font>&nbsp;<B>Sync</B>";

I also have two buttons that can set the text as above and get the Document from RichTextbox.  I’m able to set/get the value by clicking the buttons.  

The problem started when I type something in RichTextbox and I move to the another control.  

I’m not able to set anything from Button Click.  Any idea why it’s not working?  

Problem #2:

If I change LostFocus to TextChanged Event in my attached property then I’m not able to set anything.  

Any idea how to support LostFocus and TextChanged event with Rich Textbox?

Thanks in advance.

Regards,

Michael Sync

Andrew

unread,
Apr 7, 2009, 8:01:13 AM4/7/09
to wpf-di...@googlegroups.com
I think the issue is that you have not defined the DP to bind two way by default. Therefore when you set the value in the OnBoundDocumentChanged you are removing the binding (the previous local value) and replacing it with the local value that you set. So you should probably create a FrameworkPropertyMetadata instead of a PropertyMetadata and include the BindsTwoWayByDefault option.


From: Michael Sync <mchl...@gmail.com>
To: wpf-di...@googlegroups.com
Sent: Tuesday, April 7, 2009 6:06:03 AM
Subject: [WPF Disciples] PropertyChanged + LostFocus with RichTextbox Attached Property

Michael Sync

unread,
Apr 7, 2009, 12:58:13 PM4/7/09
to wpf-di...@googlegroups.com
Hello Andrew,

Thanks a lot. It solved the problem 1.

What about Problem 2? How can I support PropertyChanged UpdateTrigger (TextChanged Event)?

I got the error at box.Document = doc when I change LostFocus to TextChanged Event.

The error message is "Cannot set the Document property inside the scope of DeclareChangeBlock or BeginChange/EndChange calls."

How should I set the Document back?

Regards,
Michael Sync
--
Don't go the way life takes you.
Take life the way you go

http://michaelsync.net

Josh Smith

unread,
Apr 7, 2009, 1:09:03 PM4/7/09
to wpf-di...@googlegroups.com
Hi Michael,

It might be better if you posted these types of "how to" questions on Microsoft's WPF Forum, and then you can perhaps send out a message to this group with a link to that forum post, if you think someone here might be able to help.  That way you're more likely to get an answer quickly, the answer will have higher public visibility, and the Disciples won't start feeling like an extension of the WPF Forum.  The occasional "how to" is OK, but I just want to make sure that we're all on the same page.  :)

Thanks,
Josh

Andrew

unread,
Apr 7, 2009, 1:17:19 PM4/7/09
to wpf-di...@googlegroups.com
I'm guessing that you would need to process the TextChanged asynchronously (e.g. using Dispatcher.BeginInvoke) since that can be raised from the setter of the Document property.

Sent: Tuesday, April 7, 2009 12:58:13 PM
Subject: [WPF Disciples] Re: PropertyChanged + LostFocus with RichTextbox Attached Property

Michael Sync

unread,
Apr 7, 2009, 1:25:21 PM4/7/09
to wpf-di...@googlegroups.com
Thanks a lot, Andrew. I will try.

Hi Josh,

Thanks for letting me know this. I'm so sorry. I mis-understand about our newsgroup. I thought it might be like other newsgroups where we used to discuss with tip/trick for WPF. I will be careful next time. I won't do it again. I will read some old posts in google group as well so that I can get better idea..

Thanks a lot.

Regards,
Michael Sync

Josh Smith

unread,
Apr 7, 2009, 1:34:12 PM4/7/09
to wpf-di...@googlegroups.com
No worries, Michael.  The WPF Disciples is not a group where people ask each other "how to" questions very much. It certainly happens from time to time, but normally the threads on this group are for sharing ideas, pointing out some cool blog post or article you found and want to discuss, proposing a new feature you'd like to see in WPF or Silverlight, etc.  That, and one hell of a lot of bullshitting.  :)

Josh

Michael Sync

unread,
Apr 7, 2009, 1:36:38 PM4/7/09
to wpf-di...@googlegroups.com
Okay. Josh.. Thanks. :)

Karl Shifflett

unread,
Apr 7, 2009, 2:08:56 PM4/7/09
to wpf-di...@googlegroups.com

Michael, Josh is correct.  There are days when boots are required.  I can remember one day where a stream fisherman’s ½ body suit was required…

Reply all
Reply to author
Forward
0 new messages