Giter Club home page Giter Club logo

unitymvvmtoolkit's People

Contributors

aaisara12 avatar chebanovdd avatar cunningfox146 avatar hellfim avatar kirill-tolmachev avatar vasilevmaxim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unitymvvmtoolkit's Issues

Trying to remove item from BindableListView causes ArgumentOutOfRangeException

I've made a BindableListView that has some items that should get added or removed. When trying to remove item from list or calling Clrear on collection, I get ArgumentOutOfRangeException. My ViewModel class:

using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using ArPaint.Services.Draw;
using ArPaint.UI.Systems.Stack;
using ArPaint.UI.Views.DrawingInfo;
using ArPaint.Utils;
using UnityMvvmToolkit.Core;
using UnityMvvmToolkit.Core.Attributes;
using UnityMvvmToolkit.Core.Interfaces;

namespace ArPaint.UI.ViewModels.Home
{
    public class HomeViewModel : ViewModel
    {
        private readonly IDrawingsProvider _drawingsProvider;

        [Observable(nameof(Drawings))]
        private readonly IProperty<ObservableCollection<DrawingViewModel>> _drawings;

        public ObservableCollection<DrawingViewModel> Drawings => _drawings.Value;
        
        public ICommand CreateDrawingCommand { get; }

        public HomeViewModel(IDrawingsProvider drawingsProvider)
        {
            _drawingsProvider = drawingsProvider;

            CreateDrawingCommand = new Command(CreateDrawing);
            
            _drawings = new Property<ObservableCollection<DrawingViewModel>>(new ObservableCollection<DrawingViewModel>());
            _drawingsProvider.Drawings.CollectionChanged += OnDrawingsChanged;
            BuildDrawingsCollection();
        }

        private void OnDrawingsChanged(object sender, NotifyCollectionChangedEventArgs evt)
        {
            switch (evt.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    foreach (var item in evt.NewItems)
                    {
                        if (item is DrawingData drawing)
                            Drawings.Add(new DrawingViewModel(drawing, SelectDrawing));
                    }
                    break;
                case NotifyCollectionChangedAction.Remove:
                    foreach (var item in evt.OldItems)
                    {
                        if (item is DrawingData drawing)
                            Drawings.RemoveAll(viewModel => viewModel.Drawing == drawing);
                    }
                    break;
                default:
                    break;
            }
        }

        private void BuildDrawingsCollection()
        {
            foreach (var drawing in _drawingsProvider.Drawings)
            {
                Drawings.Add(new DrawingViewModel(drawing, SelectDrawing));
            }
        }

        private void CreateDrawing()
        {
            _drawingsProvider.SelectDrawing(null);
            ViewStack.PushView<DrawingInfoView>();
        }

        private void SelectDrawing(DrawingData drawing)
        {
            _drawingsProvider.SelectDrawing(drawing);
            ViewStack.PushView<DrawingInfoView>();
        }
    }
}

Add BindingContextProvider

To automatically provide a custom BindingContext for child elements.

public class TestItemViewModel : ICollectionItem
{
    [Observable] 
    private readonly IProperty<string> _name = new Property<string>();

    ...
}
public class TestViewModel : IBindingContext
{
    [Observable]
    private readonly IProperty<TestItemViewModel> _selectedItem;
}
[UxmlElement]
public partial class TestItemViewModelProvider : BindingContextProvider<TestItemViewModel>
{
}
<ui:UXML ...>
    <BindableUIElements.TestItemViewModelProvider binding-context-path="SelectedItem">
        <UnityMvvmToolkit.UITK.BindableUIElements.BindableLabel binding-text-path="Name" />
    </BindableUIElements.TestItemViewModelProvider>
</ui:UXML>

BindingContextProvider throws exception in Unity2023

Simple declaration of BindingContextProvider

<UnityMvvmToolkit.UITK.BindableUIElements.BindingContextProvider name="TestName"/>

Throws an exception in runtime when BindingContextProvider is created. As far as I was able to trace the problem - method Deserialize of BindingContextProvider receives a visualElement argument which is being cast to BindingContextProvider inside .As method extension, which throws an exception. Received argument has a type of VisualElement.

Stacktrace (truncated my invocation entry-point):
InvalidCastException: Specified cast is not valid.
(wrapper castclass) System.Object.__castclass_with_cache(object,intptr,intptr)
UnityMvvmToolkit.UITK.Extensions.VisualElementExtensions.As[T] (System.Object visualElement) (at ./Library/PackageCache/[email protected]/Runtime/UITK/Extensions/VisualElementExtensions.Uxml.cs:12)
UnityMvvmToolkit.UITK.BindableUIElements.BindingContextProvider1+UxmlSerializedData[TBindingContext].Deserialize (System.Object visualElement) (at ./Library/PackageCache/[email protected]/Runtime/UITK/BindableUIElements/Uxmls/BindingContextProvider.T.Uxml.cs:23) UnityEngine.UIElements.VisualElementAsset.Instantiate (UnityEngine.UIElements.CreationContext cc) (at <844b3559a9bf433db5c9639bc6cc5f04>:0) UnityEngine.UIElements.VisualTreeAsset.Create (UnityEngine.UIElements.VisualElementAsset asset, UnityEngine.UIElements.CreationContext ctx) (at <844b3559a9bf433db5c9639bc6cc5f04>:0) UnityEngine.UIElements.VisualTreeAsset.CloneSetupRecursively (UnityEngine.UIElements.VisualElementAsset root, System.Collections.Generic.Dictionary2[TKey,TValue] idToChildren, UnityEngine.UIElements.CreationContext context) (at <844b3559a9bf433db5c9639bc6cc5f04>:0)
UnityEngine.UIElements.VisualTreeAsset.CloneSetupRecursively (UnityEngine.UIElements.VisualElementAsset root, System.Collections.Generic.Dictionary`2[TKey,TValue] idToChildren, UnityEngine.UIElements.CreationContext context) (at <844b3559a9bf433db5c9639bc6cc5f04>:0)
UnityEngine.UIElements.VisualTreeAsset.CloneTree (UnityEngine.UIElements.VisualElement target, UnityEngine.UIElements.CreationContext cc) (at <844b3559a9bf433db5c9639bc6cc5f04>:0)
UnityEngine.UIElements.VisualTreeAsset.Instantiate () (at <844b3559a9bf433db5c9639bc6cc5f04>:0)
UnityEngine.UIElements.UIDocument.RecreateUI () (at <844b3559a9bf433db5c9639bc6cc5f04>:0)
UnityEngine.UIElements.UIDocument.set_visualTreeAsset (UnityEngine.UIElements.VisualTreeAsset value) (at <844b3559a9bf433db5c9639bc6cc5f04>:0)

Add ReadOnlyProperty support for BindableTextField

Feature request

Now the following code throws an exception. Even if the BindableTextField is marked as read-only.

public class NameViewModel : IBindingContext
{
    [Observable]
    private readonly IReadOnlyProperty<string> _name = new ReadOnlyProperty<string>(nameof(NameViewModel));
}
<ui:UXML xmlns:uitk="UnityMvvmToolkit.UITK.BindableUIElements" ...>
    <uitk:BindableTextField binding-value-path="Name" />
</ui:UXML>

I'd like to allow this type of binding if a BindableTextField is read-only.

Some nested members are not properly retrieved

Private/protected members declared in inherited classes are not always properly retrieved.
Suppose we have following structure of ViewModels

public class BaseViewModel { }

public class MiddleViewModel : BaseViewModel
{
    [Observable("MyTestInt")]
    private IProperty<Int32> _myTestInt;

    public MiddleClass()
    {
        _myTestInt = new Property<Int32>(123);
    }
}

public class TopLevelViewModel : MiddleViewModel
{
}

If one were to try bind TopLevelViewModel's MyTestInt from it's parent class, then exception InvalidOperationException: Property 'MyTestInt' not found. would be raised.

Auto generate ParameterValueConverter for assignable types

Will simplify the creation of BindingContextProvider by eliminating the need to write ParameterValueConverters for each ViewModel.

The following will allow to provide any ViewModel for child elements.

[UxmlElement]
public partial class CommonBindingContextProvider : BindingContextProvider<IBindingContext>
{
}

Related thread #43 (comment)

ReadOnlyPropertyWrapper doesn't report value changes

ReadOnlyPropertyWrapper<TSource, TValue> doesn't have functionality to report value changes

It happens because ValueChanged event is intentionally never invoked inside ReadOnlyPropertyWrapper.
It leads to incorrect and unexpected behaviour which might be illustrated with following example

public class MyService
{
    public IReadOnlyProperty<Int32> MyProperty => _myProperty;

    private IProperty<Int32> _myProperty = new Property<Int32>();
}

public class MyViewModel : IBindingContext
{
    [Observable("MyReadOnlyProperty")]
    private IReadOnlyProperty<Int32> _myReadOnlyProperty;

    public MyViewModel(MyService myService)
    {
        _myReadOnlyProperty = myService.MyProperty;
    }
}

Suppose MyReadOnlyProperty property is bound to BindableLabel.
Now, whenever MyService internally changes property value BindableLabel doesn't receive a callback from the wrapper and is never updated

Field commands issue.

Describe the bug

The following code leads to the Specified cast is not valid. exception. Because of trying to cast FieldInfo to PropertyInfo.

public class MyViewModel : IBindingContext
{
    [Observable]
    private readonly ICommand<string> _command = new Command<string>(Debug.Log);
}

Exception on wrapper cast

InvalidCastException: Specified cast is not valid.
UnityMvvmToolkit.Core.Internal.ObjectWrappers.PropertyWrapper`2[TSource,TValue].SetProperty (UnityMvvmToolkit.Core.Interfaces.IBaseProperty property) (at ./Library/PackageCache/[email protected]/Runtime/Core/Internal/ObjectWrappers/PropertyWrapper.TSource.TValue.cs:56)
UnityMvvmToolkit.Core.Internal.ObjectHandlers.ObjectWrapperHandler.GetProperty[TProperty,TValueType] (UnityMvvmToolkit.Core.Interfaces.IBindingContext context, UnityMvvmToolkit.Core.BindingData bindingData, System.Reflection.MemberInfo memberInfo) (at ./Library/PackageCache/[email protected]/Runtime/Core/Internal/ObjectHandlers/ObjectWrapperHandler.cs:123)
UnityMvvmToolkit.Core.BindingContextObjectProvider.GetProperty[TProperty,TValueType] (UnityMvvmToolkit.Core.Interfaces.IBindingContext context, UnityMvvmToolkit.Core.BindingData bindingData) (at ./Library/PackageCache/[email protected]/Runtime/Core/BindingContextObjectProvider.cs:208)
UnityMvvmToolkit.Core.BindingContextObjectProvider.RentReadOnlyProperty[TValueType] (UnityMvvmToolkit.Core.Interfaces.IBindingContext context, UnityMvvmToolkit.Core.PropertyBindingData bindingData) (at ./Library/PackageCache/[email protected]/Runtime/Core/BindingContextObjectProvider.cs:132)
MVVMExtensions.BindingContextObjectProviderWithCustomTemplates.RentReadOnlyProperty[TValueType] (UnityMvvmToolkit.Core.Interfaces.IBindingContext context, UnityMvvmToolkit.Core.PropertyBindingData bindingData) (at Assets/Scripts/MVVMExtensions/BindingContextObjectProviderWithCustomTemplates.cs:79)
UnityMvvmToolkit.UITK.BindableUIElements.BindableLabel.SetBindingContext (UnityMvvmToolkit.Core.Interfaces.IBindingContext context, UnityMvvmToolkit.Core.Interfaces.IObjectProvider objectProvider) (at ./Library/PackageCache/[email protected]/Runtime/UITK/BindableUIElements/BindableLabel.cs:23)

ObjectWrapperHandler provides incorrect wrappers if normal and readonly properties are used

ListView remove item issue in Unity 2021

Describe the bug

In Unity 2021, when an element is removed, the Unbind method is not called.

Current result

This leads to a lot of issues because SetBindingContext is called without resetting it.

AsyncCommand cancellation issue.

Bug description

When multiple async commands are running at the same time, cancellation only works for the last async command.

Minimal reproduction code and steps

  1. Execute StartCommand several times
  2. Execute CancelCommand
public MainViewModel()
{
    StartCommand = new AsyncCommand(StartAsync).WithCancellation();
    CancelCommand = new Command(() => StartCommand.Cancel());
}

public IAsyncCommand StartCommand { get; }

public ICommand CancelCommand { get; }

private async UniTask StartAsync(CancellationToken cancellationToken)
{
    while (cancellationToken.IsCancellationRequested == false)
    {
        await UniTask.Delay(1000, cancellationToken: cancellationToken);
        Debug.Log(nameof(StartAsync));
    }
}

Current result

Only the last command will be canceled.

Expected result

All running commands should be canceled.

Converter is ignored when types match.

Describe the bug

It is impossible to create a converter to invert the property value because the current implementation ignores the converter when the source and target types match.

GetBindableChilds ignores bindable children from template files

Method GetBindableChilds from VisualElementExtensions incorrectly handles cases with bindable elements in templates. Suppose there is an empty scene with 1 GameObject called View and 2 attached components (UI Document and TestCaseView). If one would run such scene and click THE BUTTON he would see a "Normal button pressed" in the console, however if he clicks on a pink background there is no "Background button pressed" in the console.
Listing of the files is provided below.

WindowContainer.uxml:

<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
    <ui:VisualElement name="window-root" style="flex-grow: 1;">
        <UnityMvvmToolkit.UITK.BindableUIElements.BindableButton command="BackgroundButtonCommand" name="window-closer" class="0; 0; 0;" style="position: absolute; top: 0; left: 0; bottom: 0; right: 0; background-color: rgb(236, 166, 166);" />
        <ui:VisualElement name="content-container" contentContainer="true" picking-mode="Ignore" style="flex-grow: 1; align-items: center; justify-content: space-around;" />
    </ui:VisualElement>
</ui:UXML>

TestCaseWindow.uxml:

<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
    <ui:Template name="WindowContainer" src="project://database/Assets/TestCase/WindowContainer.uxml?fileID=9197481963319205126&amp;guid=54cc8b8584dd8494a83f70ca4058d5b4&amp;type=3#WindowContainer" />
    <ui:Instance template="WindowContainer" style="flex-grow: 1;">
        <UnityMvvmToolkit.UITK.BindableUIElements.BindableButton command="NormalButtonCommand" text="THE BUTTON" name="ok-button" style="width: 300px; height: 200px; font-size: 50px;" />
    </ui:Instance>
</ui:UXML>

TestCaseViewModel.cs:

    public class TestCaseViewModel : IBindingContext
    {
        public ICommand NormalButtonCommand { get; }
        public ICommand BackgroundButtonCommand { get; }

        public TestCaseViewModel()
        {
            NormalButtonCommand = new Command(() => Debug.Log("Normal button pressed"));
            BackgroundButtonCommand = new Command(() => Debug.Log("Background button pressed"));
        }
    }

TestCaseView.cs:

    public class TestCaseView : DocumentView<TestCaseViewModel>
    {
    }

Collect only observable fields from ViewModel.

Describe the bug

Private fields are not ignored when building the ViewModel.

Code example

public class MainViewModel : IBindingContext
{
    private readonly IProperty<int> _count = new Property<int>();

    public IReadOnlyProperty<int> Count => _count;
}

Current result

Exception: "ArgumentException: An item with the same key has already been added." will be thrown.

Expected result

The _count field should be ignored if it is private or not marked with the Observable attribute.

Unknown type: 'UnityMvvmToolkit.UITK.BindableListView'

Describe the bug

BindableListView doesn't work in the UI Toolkit.

Minimal reproduction code and steps

  1. Unity 2023.1.14f
  2. UnityMvvmToolkit 1.1.8
  3. I'm using manual for BindableListView - https://github.com/LibraStack/UnityMvvmToolkit/tree/c9b55759c90b16a5f2a1f8eea3bdb887a3df671a#bindablelistview
  4. Create UI document with BindableListView
  5. Start UI builder or application

Current result

UI Builder:
image

Plus, there isn't such custom control in UI builder
image

Expected result

BindableListView is working

Additional information, screenshots, or code examples

View:

<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements"
  xmlns:uitk="UnityMvvmToolkit.UITK"
  editor-extension-mode="False">

  <Style
    src="project://database/Assets/Art/UI/Character/Inventory.uss" />

  <ui:VisualElement name="Inventory" class="inventory" contentContainer="true">
    <uitk:BindableListView binding-items-source-path="Items" />
  </ui:VisualElement>
</ui:UXML>

Exception in Unity debug console:

Element 'UnityMvvmToolkit.UITK.BindableUIElements.BindableListView' has no registered factory method.
UnityEngine.UIElements.UIDocument:OnValidate () (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Core/GameObjects/UIDocument.cs:708)

Is explicit IProperty necessary?

Feature request

Wouldn't it be cool when you don't need the IProperty Interface manually. So that you just add a annotation to a field of your model object aka scriptable object. And the binder will create the Property for it and updates the model object itself.

Problem it solves

Currently I have something like that:

    public class HoverData : ScriptableObject
    {
        public float height;
        public float power;
    }

And need an additional model object like:

    public class HoverModel : IBindingContext
    {
        public IProperty<float> Height { get; }  
        public IProperty<float> Power   { get; }

        public HoverModel(HoverData hoverData){
            Height = new Property<float>();
            Power = new Property<float>();

            Height.ValueChanged += (_, f) => hoverData.height = f;
            Power.ValueChanged += (_, f) => hoverData.power = f;
        }
    }

would be cool when we could do something like:

public class HoverData : ScriptableObject
{
    [Property]
    public float height;
    [Property]
    public float power;

   // And maybe also for commands?
   [Command]
   public void DoStuff() { }
}

Describe alternatives you've considered

Additional information, screenshots, or code examples

Maybe I don't understand it correctly and you can show me a better way.

ArgumentException when using several converters with same TFrom type

Suppose you have following files:

MyView.uxml
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
    <ui:VisualElement style="flex-grow: 1; align-items: center; justify-content: center;">
        <MyCustomControl binding-bool-path="ResultProperty, ResultToBooleanConverter" text="Label" style="font-size: 130px;" />
        <MyCustomControl binding-bool-path="ResultProperty, InvertedResultToBooleanConverter" text="Label Inv" style="font-size: 130px;" />
    </ui:VisualElement>
</ui:UXML>
Result.cs
    public enum Result
    {
        Defeat,
        Victory,
    }
ResultToBooleanConverter.cs
    public class ResultToBooleanConverter : PropertyValueConverter<Result, Boolean>
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override Boolean Convert(Result value)
        {
            return value == Result.Victory;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override Result ConvertBack(Boolean value)
        {
            return value ? Result.Victory : Result.Defeat;
        }
    }
InvertedResultToBooleanConverter.cs
    public class InvertedResultToBooleanConverter : PropertyValueConverter<Result, Boolean>
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override Boolean Convert(Result value)
        {
            return value != Result.Victory;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override Result ConvertBack(Boolean value)
        {
            return value ? Result.Defeat : Result.Victory;
        }
    }
MyView.cs
    public class MyView : DocumentView<MyViewModel>
    {
        protected override IValueConverter[] GetValueConverters()
        {
            return new IValueConverter[] { new ResultToBooleanConverter(), new InvertedResultToBooleanConverter() };
        }
    }
MyViewModel.cs
    public class MyViewModel : IBindingContext
    {
        public IProperty<Result> ResultProperty { get; }

        public TestCaseViewModel()
        {
            ResultProperty = new Property<Result>(Result.Victory);
        }
    }
MyCustomControl.cs
    [UxmlElement]
    public partial class MyCustomControl : VisualElement, IBindableElement
    {
        [UxmlAttribute("binding-bool-path")]
        private String _bindingBoolPath { get; set; }
        private PropertyBindingData _isDisplayPathBindingData;

        private IReadOnlyProperty<Boolean> _boolProperty;

        public void SetBindingContext(IBindingContext context, IObjectProvider objectProvider)
        {
            if (String.IsNullOrWhiteSpace(_bindingBoolPath))
            {
                return;
            }

            _isDisplayPathBindingData ??= _bindingBoolPath.ToPropertyBindingData();

            _boolProperty = objectProvider.RentProperty<Boolean>(context, _isDisplayPathBindingData);
            _boolProperty.ValueChanged += OnBoolPropertyValueChanged;

            UpdateControlValue(_boolProperty.Value);
        }

        public void ResetBindingContext(IObjectProvider objectProvider)
        {
            UpdateControlValue(false);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        protected virtual void UpdateControlValue(Boolean newValue)
        {
            Debug.Log($"Value changed to: {newValue}");
        }

        private void OnBoolPropertyValueChanged(Object sender, Boolean flag)
        {
            UpdateControlValue(flag);
        }
    }

This configuration produces following exception

Exception
ArgumentException: An item with the same key has already been added. Key: -1662977815
System.Collections.Generic.Dictionary`2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) (at <835c05e113da4a69bb097e93a682f230>:0)
System.Collections.Generic.Dictionary`2[TKey,TValue].Add (TKey key, TValue value) (at <835c05e113da4a69bb097e93a682f230>:0)
UnityMvvmToolkit.Core.Internal.ObjectHandlers.ValueConverterHandler.RegisterValueConverter (UnityMvvmToolkit.Core.Interfaces.IValueConverter valueConverter) (at D:/Projects/Bin/UnityMvvmToolkit/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/Core/Internal/ObjectHandlers/ValueConverterHandler.cs:74)
UnityMvvmToolkit.Core.Internal.ObjectHandlers.ValueConverterHandler.RegisterValueConverters (UnityMvvmToolkit.Core.Interfaces.IValueConverter[] converters) (at D:/Projects/Bin/UnityMvvmToolkit/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/Core/Internal/ObjectHandlers/ValueConverterHandler.cs:43)
UnityMvvmToolkit.Core.Internal.ObjectHandlers.ValueConverterHandler..ctor (UnityMvvmToolkit.Core.Interfaces.IValueConverter[] valueConverters) (at D:/Projects/Bin/UnityMvvmToolkit/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/Core/Internal/ObjectHandlers/ValueConverterHandler.cs:18)
UnityMvvmToolkit.Core.BindingContextObjectProvider..ctor (UnityMvvmToolkit.Core.Interfaces.IValueConverter[] converters, System.Collections.Generic.IReadOnlyDictionary`2[TKey,TValue] collectionItemTemplates) (at D:/Projects/Bin/UnityMvvmToolkit/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/Core/BindingContextObjectProvider.cs:26)
UnityMvvmToolkit.Common.MonoBehaviourView`1[TBindingContext].GetObjectProvider () (at D:/Projects/Bin/UnityMvvmToolkit/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/Common/MonoBehaviourView.cs:75)
UnityMvvmToolkit.Common.MonoBehaviourView`1[TBindingContext].SetBindingContext () (at D:/Projects/Bin/UnityMvvmToolkit/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/Common/MonoBehaviourView.cs:99)
UnityMvvmToolkit.Common.MonoBehaviourView`1[TBindingContext].Awake () (at D:/Projects/Bin/UnityMvvmToolkit/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/Common/MonoBehaviourView.cs:28)

ObservableAttribue support for private properties

Hi! I would like to have an ObservableAttribute support for private properties.

Currently it only supports private fields.

In cases you don't want to expose your private/protected properties, but still want to make them available just to the View having ObservableAttribute on such properties would be a good thing

Support of new Unity UxmlElement/UxmlAttribute attributes

New versions of Unity (2023.2+) provide built-in attributes for simple UI Toolkit elements declaration.

Unfortunately they are not compatible with Bindable elements provided with MVVM toolkit out of the box.

I suggest to add support for them with something like #if UNITY_2023_2_OR_NEWER

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.