ReadProperty vs Property binding

Hello,

I’ve stumbled upon finding the difference between these two in general.

One reason is that ReadProperty should work according the documentation as I have done it here: https://gitlab.com/yavoryankov/fuse-binding/blob/master/Components/RoundButton.ux

However I get this:

RoundButton.ux(13): E8001: 'this' declared in MainView.ux(1) is a member of 'MainView' and cannot be accessed from 'RoundButton'. To make this work, consider making 'RoundButton' an ux:InnerClass of 'MainView'.
RoundButton.ux(13,1): Error E8001: 'this' declared in MainView.ux(1) is a member of 'MainView' and cannot be accessed from 'RoundButton'. To make this work, consider making 'RoundButton' an ux:InnerClass of 'MainView'.
RoundButton.ux(13): E8001: 'this' does not contain property 'LabelA'
RoundButton.ux(13,1): Error E8001: 'this' does not contain property 'LabelA'

In the other component https://gitlab.com/yavoryankov/fuse-binding/blob/master/Components/Rectanglez.ux where it is not a button but just a rectangle - the same is good to go.

So I want to know the difference. And also some tips how I can get to the root cause with messages like these?

Hi, thanks for posting!

{ReadProperty is a one-way binding (data-source-to-property) and {Property is a two-way binding (also property-to-data-source).

If you have encountered any other differences between the two, that might be a bug in the UX compiler. I’ll file an issue to have it investigated. In the meantime, does it help to qualify the property with this. ?

As far as I could debug it, the problem is that you’re assigning a Name to the ux:Class definition.

The Rectangle case works because you didn’t put a name on it.

So the new RoundButton.ux that works should look like this:

<Button ux:Class="RoundButton" ClipToBounds="false" Margin="0,0,0,4" Padding="20,7,20,7">
  <string ux:Property="Label"/>
  <Text ux:Name="buttonText" TextColor="#666666" Value="{Property this.Text}" TextAlignment="Center"/>
  <Rectangle Layer="Background" CornerRadius="25">
    <SolidColor ux:Name="buttonBg" Color="#fff"/>
    <Stroke Width="1" ux:Name="buttonStroke" Brush="#F4F4F4"/>
  </Rectangle>
  <WhileHovering>
    <Change buttonStroke.Width="1" Duration="0.3" Easing="CircularIn"/>
    <Change buttonStroke.Color="#fbe4d4" Duration="0.3" Easing="CircularIn"/>
  </WhileHovering>

  <Selectable Value="{ReadProperty Label}" />

  <Clicked>
    <ToggleSelection />
  </Clicked>

  <WhileSelected>
    <Change buttonBg.Color="#FC8535" Duration=".3"/>
  </WhileSelected>

</Button>

Note that we can still use the this.* qualifier since it’s implicitly available within a ux:Class, and you don’t need to explicitly define a self name on the node.

After investigating this a bit more, we’ve found the following.

this is the implied Name of a ux:Class, so you can refer to properties inside of a class by either omitting the prefix {ReadProperty Property} or by using it {ReadProperty this.Property}.

When you assign an explicit Name to a ux:Class - which you might need to do when you’re working with nested ux:Classes - then the implied this is replaced by the new name you gave it and this isn’t available anymore. So in this case, you are required to refer to class properties by using the explicit name you assigned, like so: {ReadProperty theName.Property}.

Hope this helps!