steveh
Topic Author
Posts: 36
Joined: 07 Oct 2019, 12:50

Collection of BaseBinding

27 Nov 2020, 13:31

Hi guys,

We have a "CustomTextBlock" which derives from a regular "TextBlock" and allows us to control the way the text block works. We want to be able to replace some of the text within based on some string formatting rules:
<CustomTextBlock Text="Some Variable: {SomeVariable}" />
Right now the "{SomeVariable}" sub string is just replaced in code, something like:
CustomTextBlock *pTB = GetTextBlock();
pTB->AddVariable("SomeVariable", "SomeValue");
This will then internally rebuild the string and the text will then look like

Some Variable: SomeValue

I want full binding support for this in the editor. Ideally I want something like the following:
<CustomTextBlock Text="Some Variable: {SomeVariable}" >
    <CustomTextBlock.Variables>
        <CustomTextBlockVariable Variable="SomeVariable" Binding="{Binding SomeValueFromDataContext}" />
    </CustomTextBlock.Variables>
</CustomTextBlock>
Does this sound reasonable? I've looked online and I've not seen a nice way to do this. I've looked into how BaseTrigger does it and it seems fairly complicated by having to create a binding listener and then register the CustomTextBlockVariables as a tree node and then attach / detach them at runtime. I'm willing to look more into this but I was just wondering if there was a simpler way to try to do what I'm doing. Perhaps this would work better as a converter instead with a multi data binding for the variables?

Cheers,

-Steven
 
User avatar
sfernandez
Site Admin
Posts: 2254
Joined: 22 Dec 2011, 19:20

Re: Collection of BaseBinding

27 Nov 2020, 13:47

Apart from that custom text formatting, does the CustomTextBlock add anything else to the base TextBlock?

Why don't use a Behavior to extend the default TextBlock? Something like this:
<TextBlock>
  <i:Interaction.Behaviors>
    <local:TextBlockFormatBehavior Format="Some Variable: {SomeVariable}">
      <local:Variable Name="SomeVariable" Value="{Binding SomeValueFromDataContext}"/> 
    </local:TextBlockFormatBehavior>
  </i.Interaction.Behaviors>
</TextBlock>
The behavior will do the formatting logic based on the Format property and the variables added, and then do a SetText() or add all the necessary Inlines on the associated TextBlock.

The list of variables will be a dependency property of type FreezableCollection and each Variable an Animatable, so bindings will resolve correctly.
You can also add a ContentPropertyMetaData to the reflection block to indicate that "Variables" property is the content property to avoid writing the <local:TextBlockFormatBehavior.Variables> node in xaml.

The variable Value property will just be a BaseComponent dependency property, so you can assign anything there from the ViewModel. This is pretty similar to how interactivity data trigger values are defined.

Do you think that could work?
 
User avatar
sfernandez
Site Admin
Posts: 2254
Joined: 22 Dec 2011, 19:20

Re: Collection of BaseBinding

27 Nov 2020, 13:55

Perhaps this would work better as a converter instead with a multi data binding for the variables?
If the formatting is just for assigning properties then using a MultiBinding with a StringFormat is the easiest way, no need for a converter either:
<TextBlock>
  <TextBlock.Text>
    <MultiBinding StringFormat="Some variables: {0} and {1}">
      <Binding Path="Variable1" />
      <Binding Path="Variable2" />
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>
 
steveh
Topic Author
Posts: 36
Joined: 07 Oct 2019, 12:50

Re: Collection of BaseBinding

27 Nov 2020, 13:59

Hey Sergio, much appreciated for the rapid response. Yes, the behaviour sounds like a much better idea! I think that will work great.

And the custom text block right now doesn't do much, it's just doing some simple localisation (which I know could be done via a converter) but we plan to expand this in the future to add support for rich text boxes where we generate inline text elements from some string parsing, e.g:

"[c=red][fs=23]Hello[/fs] World!"

And that would create the relevant text inlines based from that parsed text. We also need something like this to generate vector images for button prompts, e.g:

"Press [button:primary] to start"

As localisation might cause these buttons to change where they are in the string. I was going to wrap all this logic up in a custom control which derives from a TextBlock (localisation, rich text, variable parsing).

-Steven
 
User avatar
sfernandez
Site Admin
Posts: 2254
Joined: 22 Dec 2011, 19:20

Re: Collection of BaseBinding

27 Nov 2020, 17:01

Even if you need more advanced formatting (like coloring, add bold or italic, add images, hyperlinks, emojis...) the Behavior can generate the inlines and add them to the associated TextBlock, we have other clients doing that, you won't need a custom TextBlock control to do that.

Our recommendation is always to avoid creating custom controls unless strictly necessary and are more in favor of creating behaviors.

Who is online

Users browsing this forum: jsteedVR and 3 guests