views:

231

answers:

1

I need to put data from two different datasourses in the same textbox. The text that comes from the first one have to be bolded and the secound normal.

It's there a possibility to do this in WPF?

+1  A: 

Hi! You cannot bind (or multibind) to Document property of RichTextBox, because it is NOT a DependencyProperty (strange!!!)!!! See this link for a really easy way of subclassing RichTextBox to create your own BindableRichTextBox or this post for another workaround.

Now you can use MultiBinding with a custom IMultiValueConverter to achieve the results. Since you have not given much details of your problem, I can only give you an overall idea of what you should do:

<!--NOTE: Include xmlns:local=" .. " appropriately for your project-->
<Window.Resources>
    <sys:String x:Key="SourceA">This text will be normal..</sys:String>
    <sys:String x:Key="SourceB">This text will be Bold!!!</sys:String>
</Window.Resources>

And now you can do like this:

<local:BindableRichTextBox>
    <!--<local:BindableRichTextBox.Document>-->
        <MultiBinding Converter="{x:Static local:MySourceBToBoldConverter.Instance}">
            <Binding Source="{StaticResource SourceA}" />
            <Binding Source="{StaticResource SourceB}" />
        </MultiBinding>
    <!--</local:BindableRichTextBox.Document>-->
</local:BindableRichTextBox>

And then create a class MySourceBToBoldConverter that inherits from IMultiValueConverter like this:

public class MySourceBToBoldConverter : IMultiValueConverter
{
    public static readonly MySourceBToBoldConverter Instance = new MySourceBToBoldConverter();

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        //Now you'll get value from Source A as value[0]
        //           and value from Source B as value[1]
        //Do whatever you want like bold etc...
        //and return the result

        string normalText = values[0] as string;
        string boldText = values[1] as string;

        Bold bold = new Bold();
        bold.Inlines.Add(boldText);

        Paragraph para = new Paragraph();
        para.Inlines.Add(normalText);
        para.Inlines.Add(bold);

        FlowDocument rtbDocument = new FlowDocument();
        rtbDocument.Blocks.Add(para);

        return rtbDocument;
    }

    public object[] ConvertBack(object value, ... )
    {
        //Convert the object returned by Convert() back 
        //to its original form if it's possible;
        //otherwise throw not supported exception ;)

        throw new NotImplementedException();
    }
}

Currently I don't have my work PC with me that has VS installed, so I can't give you a working example, but go ahead and search google/msdn/stackoverflow 4 MultiBinding and IMultiValueConverter and you'll find some good examples out there.

Check the working example here.

Regards,
Mihir Gokani

Mihir Gokani
A 'Binding' cannot be set on the 'Source' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject. A have this error and it seems that your solution will not work
Alin
A 'MultiBinding' cannot be set on the 'Document' property of type 'RichTextBox'. A 'MultiBinding' can only be set on a DependencyProperty of a DependencyObject.
Alin
I really apologise for answering in a hurry. After a bit of research I came to know that `Document` property of `RichTextBox` isn't even bindable!!! I've corrected my answer. You should *first* make it **bindable**, after that you can use `MultiBinding` as I've suggested. Hope this helps :)
Mihir Gokani
And sorry because I still haven't tested this myself for the same reason. But if you follow the links, it's working with simple `Binding` - so it should also work with `MultiBinding`. Good luck!
Mihir Gokani
Did you manage to create a BindableRichTextBox Class? I try to copy this class from here http://blogs.chimpswithkeyboards.com/jonshute/archive/2007/10/04/WPF-Binding-to-RichTextBox.Document.aspx but it has errors.
Alin
Yes.. now I've finally tested it myself (see modified answer). The `BindableRichTextBox` class from link works perfectly. What kind of error are you getting?
Mihir Gokani
I've included the wrong namespace
Alin
Your example works only if a fave static resources. If i try to Bind the `Source` I have the following error A 'Binding' cannot be set on the 'Source' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
Alin
You might be doing something wrong. Why are you binding `Source`?? I don't think `Source` is a `DependencyProperty`. Can you please show your code what you are trying to do?
Mihir Gokani
I can't paste the code here, so I've uploaded my test project here http://www.transferbigfiles.com/Get.aspx?id=c2520dbb-b6d7-4512-9b29-02e71d97da07
Alin
Ok... have a look at modified code especially the binding part: http://cid-092d535af13fe697.skydrive.live.com/self.aspx/.Public/WpfApplication6-Modified.zip
Mihir Gokani
I think that my problem is that I try to insert `BindableRichTextBox` in a `DataTemplate` for la `ListBox` and I don't know what to put at `DataContext`.
Alin
Do you mind if you could give an example for a `DataTemplate` and a `ListBox` ?
Alin
Check `ItemsSource` property. You can find some good examples here: http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemtemplate.aspxOr, search google (http://www.google.com/search?q=+site:stackoverflow.com+listbox+itemtemplate+multibinding). Don't be afraid of MultiBinding as the technique is same as *normal* binding.
Mihir Gokani
<ListBox x:Name="MessageListBox" ItemsSource="{Binding Messages.View}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <helpers:BindableRichTextBox> <MultiBinding Converter="{x:Static converters:JoinBoldSubjectWithMessageExcerptConverter.Instance}"> <Binding Path="{Binding subject}" /> <Binding Path="{Binding message_excerpt}" /> </MultiBinding> </helpers:BindableRichTextBox> </StackPanel> </DataTemplate> </ListBox.ItemTemplate></ListBox>Did I miss something?
Alin
What kind of error you are getting? What is `Messages`, what is `Messages.View`? The code looks fine except `Path="{Binding ... }"`, instead, just use `Path=" ... "`.
Mihir Gokani
It work's when I've change `Path="{Binding ... }"` with `Path=" ... "`
Alin