Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Bindings for other properties #9

slimshader started this conversation in General
Discussion options

Is it planned to add possibility to bind other properties than the "main ones" for specific control, for example binding a IProperty to alpha value of the background.

You must be logged in to vote

Replies: 2 comments 1 reply

Comment options

Hi there.

The package provides a complete set of tools to implement binding to any property you wish.

The following code shows how to make bindable Opacity and BackgroundColor properties.

public class TestViewModel : IBindingContext
{
 public IReadOnlyProperty<int> Opacity { get; } = new ReadOnlyProperty<int>(15);
 public IReadOnlyProperty<Color> BackgroundColor { get; } = new ReadOnlyProperty<Color>(Color.red);
}
public class BindableVisualElement : VisualElement, IBindableElement
{
 private PropertyBindingData _opacityPropertyBindingData;
 private PropertyBindingData _backgroundColorPropertyBindingData;
 private IReadOnlyProperty<int> _opacityProperty;
 private IReadOnlyProperty<Color> _backgroundColorProperty;
 
 public string BindingOpacityPath { get; private set; }
 public string BindingBackgroundColorPath { get; private set; }
 public void SetBindingContext(IBindingContext context, IObjectProvider objectProvider)
 {
 _opacityPropertyBindingData ??= BindingOpacityPath.ToPropertyBindingData();
 _backgroundColorPropertyBindingData ??= BindingBackgroundColorPath.ToPropertyBindingData();
 _opacityProperty = objectProvider.RentReadOnlyProperty<int>(context, _opacityPropertyBindingData);
 _opacityProperty.ValueChanged += OnOpacityValueChanged;
 
 _backgroundColorProperty = objectProvider.RentReadOnlyProperty<Color>(context, _backgroundColorPropertyBindingData);
 _backgroundColorProperty.ValueChanged += OnBackgroundColorValueChanged;
 SetOpacity(_opacityProperty.Value);
 SetBackgroundColor(_backgroundColorProperty.Value);
 }
 public void ResetBindingContext(IObjectProvider objectProvider)
 {
 _opacityProperty.ValueChanged -= OnOpacityValueChanged;
 _backgroundColorProperty.ValueChanged -= OnBackgroundColorValueChanged;
 objectProvider.ReturnReadOnlyProperty(_opacityProperty);
 objectProvider.ReturnReadOnlyProperty(_backgroundColorProperty);
 _opacityProperty = null;
 _backgroundColorProperty = null;
 SetOpacity(100);
 SetBackgroundColor(default);
 }
 private void OnOpacityValueChanged(object sender, int newValue)
 {
 SetOpacity(newValue);
 }
 private void OnBackgroundColorValueChanged(object sender, Color newColor)
 {
 SetBackgroundColor(newColor);
 }
 private void SetOpacity(int value)
 {
 style.opacity = value / 100.0f; // You can write a PropertyValueConverter<int, float> for this conversion.
 }
 private void SetBackgroundColor(Color newColor)
 {
 style.backgroundColor = newColor;
 }
 public new class UxmlFactory : UxmlFactory<BindableVisualElement, UxmlTraits> { }
 public new class UxmlTraits : VisualElement.UxmlTraits
 {
 private readonly UxmlStringAttributeDescription _bindingOpacityAttribute = new()
 { name = "binding-opacity-path", defaultValue = "" };
 private readonly UxmlStringAttributeDescription _bindingBackgroundColorAttribute = new()
 { name = "binding-background-color-path", defaultValue = "" };
 public override void Init(VisualElement visualElement, IUxmlAttributes bag, CreationContext context)
 {
 base.Init(visualElement, bag, context);
 var bindableVisualElement = (BindableVisualElement) visualElement;
 bindableVisualElement.BindingOpacityPath =
 _bindingOpacityAttribute.GetValueFromBag(bag, context);
 bindableVisualElement.BindingBackgroundColorPath =
 _bindingBackgroundColorAttribute.GetValueFromBag(bag, context);
 }
 }
}

Is this what you were looking for?

You must be logged in to vote
1 reply
Comment options

Or you can use a UnityMvvmToolkit.Generator to achieve the same results but with just a few lines of code.

[BindableElement]
public partial class BindableVisualElement : VisualElement
{
 [BindableProperty("Opacity")]
 private IReadOnlyProperty<int> _opacityProperty;
 [BindableProperty("BackgroundColor")]
 private IReadOnlyProperty<Color> _backgroundColorProperty;
 partial void AfterSetBindingContext(IBindingContext context, IObjectProvider objectProvider)
 {
 OnOpacityPropertyValueChanged(_opacityProperty?.Value ?? 100);
 OnBackgroundColorPropertyValueChanged(_backgroundColorProperty?.Value ?? default);
 }
 partial void AfterResetBindingContext(IObjectProvider objectProvider)
 {
 OnOpacityPropertyValueChanged(100);
 OnBackgroundColorPropertyValueChanged(default);
 }
 partial void OnOpacityPropertyValueChanged(int value)
 {
 style.opacity = value / 100.0f;
 }
 partial void OnBackgroundColorPropertyValueChanged(Color value)
 {
 style.backgroundColor = value;
 }
}
Comment options

Thanks! This looks fantastic, will try that asap.

Tbh, I am in the process of evaluation this package vs "raw" UI Toolkit + UniMob. On one hand UniMob / MobX feels super powerful and in essence simpler but this packages' deep support for ui toolkit + source generators + out of the box optimized lists etc. looks fantastic too. Tough choice but great time to be Unity UI dev ;)

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /