Search Unity

[Released] Simple Bind - Easily implement property and event binding

Discussion in 'Assets and Asset Store' started by softsource-admin, Dec 3, 2015.

  1. softsource-admin

    softsource-admin

    Joined:
    Apr 10, 2015
    Posts:
    1
    Simple Bind from SoftSource Consulting

    Purchase | Overview | Support

    Simple Bind from SoftSource Consulting provides a MVVM-style binding experience for Unity applications! Simple Bind lets Unity developers easily implement powerful binding functionality similar to WPF, AngularJS, and other MV* frameworks.

    Key functionality includes:
    • Property binding
    • Event binding to Unity Events
    • Inheritable BindingContext (data context)
    • Editor for easy configuration of bindings
    • Value Converters / Multi-Value Converters
    • Built-in Value Converters (int to string, double to string, etc.)
    • Built-in Multi-Value Converters (doubles to string, RGB to color)
    • Data bound controls (Items Control, List Box, Tooltip)
    • Easily create data bound Item Templates
    Update: V0.2 has been released, introducing the following new features:
    • Editor context menu integration allowing the creation of Simple Bind Controls directly from the context menu
    • Command class allowing Execute/CanExecute functionality to be easily bound from the View Model to the View
    • Command Button control that fully utilizes the Command class
    • Simple Prefab Editor to simplify View editing
    • Simple Bookmarks to switch quickly between Game Objects within the hierarchy
    • Variety of defect fixes within the core binding classes
    Compatible with Android and iOS.





     
    Last edited: Jan 22, 2016
  2. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    We had a great question come in this morning via the Simple Bind support e-mail unity@sftsrc.com and we wanted to create a short video to answer that question and provide another example of how Simple Bind can work within your Unity project.

    To summarize the users question he asked:

    "I want the user to be able to select a clickable spot on a 3D map which dynamically toggles a corresponding item in a list view and vice-versa. The notion of vice-versa is important to me and I would like to keep it really simple.
    Do you think Simple Bind (as is v0.1) could help me to simply achieve that?"

    The quick and simple answer to that is Yes. Simple Bind can be used for 3D, 2D and uGUI GameObjects and Components. Really, any GameObject can work with Simple Bind.

    The more in depth answer lies in the existing architecture of your project. Simple Bind can help solve this problem by simply binding values between GameObjects or it could be used to facilitate a more loosely coupled MVVM architecture where the different pieces are backed by the same Model.

    Since the user was asking for the simple answer that is what we will cover in this video located on our YouTube channel:
     
  3. Tropobor

    Tropobor

    Joined:
    Mar 24, 2014
    Posts:
    73
    Thanks for the detailed explanation and dedicated video
    And yes, you have indeed fully answered my question :)

    In term of architecture, not so sure yet if I will use a MV**, this is still under study, hence my interest in your package.
    Of course I do have many questions which are driven by :
    "it could be used to facilitate a more loosely coupled MVVM architecture where the different pieces are backed by the same Model"
    Well...So... what is coming next? An approximate idea how and when V1.0 will be? More details about features in ListBoxControl? DataTemplate?
    (I promise I will try to be patient=)
     
  4. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    I am glad to hear that I was able to answer your question fully.

    As to your other questions...

    We have a very long and broad list of potential features that we would like to add to the Simple Bind package. However, we are trying to be careful about what we actually add to make sure that what is in the product is useful and easily integrated into any Unity project.

    This is actually one of the main reasons that we decided to put out a V0.1. We wanted to release the core mechanic (data and event binding) and then get feedback from the community as to how they would want to utilize these mechanics. Your feedback will help us decided which items to pull off our backlog list to work on next :)

    We do not have an exact road-map yet, but I can say that V0.2 is coming along nicely.

    Among the new/updated features will be:
    - Command Binding / Command Button (similar to ICommand from WPF)
    - Content Control with Data-Typed Template resolution
    - Integration into the Unity Editor for easier access to Simple Bind Controls
    - Better handling for generic UnitEvents
    - Additional error and fallback handling

    If you have specific use cases or features that you would like to see in Simple Bind please let us know. If they match with our goals we will bump them up in priority to get them to you faster.

    There are also several more demo videos in the works that will cover the controls released in V0.1. Be watching this thread and we will let you know when they become available.
     
  5. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    The next video in the Simple Bind series has been released and covers the basics of using the Simple Bind Tool Tip.
     
  6. Tropobor

    Tropobor

    Joined:
    Mar 24, 2014
    Posts:
    73
    This is interesting because your system apparently greatly opens the possibility of new interaction scenarios.

    But for now, I noticed your package because I'm looking for ways to achieve exactly what you demonstrate in its most basic form :
    Connect 3D Objects with matching Ui items through a vice versa binding.
    What can happen (and how your asset could help) if we have, let's say, some decades of those?
    I know you may answer that there are many ways to achieve that and it depends of the architecture.
    I do agree so let's start simple and reformulate the question:
    Using Simple Bind, what would be the simplest way to :
    Connect fifty 3D Objects with matching Ui items through a vice versa binding?
     
  7. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    Tropobor, thanks for the great questions.

    I spent a little bit of time today and put together a second video to answer your question about how to dynamically generate model information and then use that model information to provide two-way binding between 3D Objects and multiple uGUI items.

    It is a bit longer than the other videos but I hope it will provide a lot more detail about how Simple Bind can be used in a data driven application.

    In this demo we create 100 random Planets, display each planet as a 3D Object in World space using a Simple Bind Items Control and in the UI using a Simple Bind List Box.

    We will also be using multiple binding mechanics, value converts and event binding.

    Please let me know what new questions this video brings up :)
     
  8. Tropobor

    Tropobor

    Joined:
    Mar 24, 2014
    Posts:
    73
    Thank you. Your explanation is clear, organized, generous and generic.
    Considering my angle regarding your asset, your video largely outweigh what I was going to ask next.
    I really wish other designers submit their issues and suggest other forms of architectures that can be built with this.
     
  9. RealityDotStop

    RealityDotStop

    Joined:
    Mar 4, 2013
    Posts:
    42
    Ahhh... as a fellow WPF convert, this is like taking my shoes and socks off after a long day of work and wiggling my toes in thick pile carpet. Seriously, I can't think of any framework I've ever learned that had as large of a payoff as WPF has. Once you get past the learning escarpment, it is remarkable.

    I just got the package last night, so I'm still feeling my way around and I don't have my UI fully ready to take advantage of any more advanced features or event binding (though I can vouch I can bind text values - and I have a strong desire to throttle whoever came up with the UGUI layout engine).

    Two thoughts immediately jump to mind. Have you ever used ReactiveUI for WPF? We use an older version (.NET 4.0 based, so like Unity it is pre-"await") at work, and had good success. I have noticed there is a UniRX....

    So, as I ask this with little knowledge of how you've implemented this yet: how does asynchronous updates affect the data binding? I notice that you are NOT relying on INotifyPropertyChanged, as you don't require changes to the scripts to bind to them (one of the reasons why I chose Simple Bind over Data Binding for Unity - Data Binding for Unity appears heavily geared to UI elements with custom scripts for custom UI elements and special "Context" base classes, etc. ). This leads me to believe you're creating a property accessor reference and comparing the values every update, which would run into locking issues in an asynchronous update.


    Though two, I'm using "New UI Widgets" as well, and it has a list box that I'm looking to add the equivalent of a WPF ItemTemplateSelector to it. I notice you mentioned template resolution as an upcoming feature. Is there a good way of doing this now, or should I just hold off for now?
     
    TeagansDad likes this.
  10. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    PixelHero - Welcome to the Simple Bind forum and thanks for your purchase.

    I have not used ReactiveUI for WPF but have used other Rx frameworks and looked into UniRx a bit. At this point there are no plans for Simple Bind to incorporate any async style bindings directly, but that does not mean we will not add them to the investigation backlog.

    Our primary goal in creating Simple Bind was to make implementing binding as seamless as possible without the need to modify existing classes or scripts. You are exactly correct in your deduction that we are creating property references and checking the value during the LateUpdate method each frame. This method of updating the binding does come with some performance implications and is by far the most brute force. However, it was the best first step to accomplishing our goals and is needed to allow binding to existing Unity Components and third party assets.

    One of the future steps for Simple Bind will be to integrate a check to determine if the Binding Context implements INotifyPropertyChanged. If it does then the Binding will subscribe to the PropertyChanged event and skip the LateUpdate check. This will improve performance and give the underlying context (ViewModel) the ability to control the update timing and mechanism if needed (such as async updates with deferred change notification). However, this also requires that the developer follows the INotifyPropertyChanged pattern in their classes. (If you look into the Simple Bind code you will notice that there are a few hooks already in place for this)

    With the current binding mechanism async updates to one way bindings should not cause any issues (however, it has not been tested) since it is a read only operation and if the value updates on the background thread between the change check and the actual getting of the value then the latest value will always be used. The check also happens every frame so any miss in the change check will be caught on the next frame. However, asycn updates on a two way binding would potentially cause issues as there would be a possible race condition between both sides of the binding trying to update at the same time.

    As for Template Selectors, there is not an easy way to accomplish this in V0.1. However, V0.2 does include a Content Control that allows basic Data Typed Template Selection. With the holidays the V0.2 release was delayed sightly, but we are putting the final touches on it now.

    Please let me know if I have answered your questions and if you have any additional comments or concerns.
     
    TeagansDad likes this.
  11. RealityDotStop

    RealityDotStop

    Joined:
    Mar 4, 2013
    Posts:
    42
    Actually, yes, that was very informative, thank you!

    My particular interest in the async comes from layering a view on a heavy multi-core simulation. This simulation core is "unity-free" and fits very nicely into an MV* paradigm. This approach has many advantages, and binding makes the interacting with the user interface elements that much easier. As of right now, I'll probably have to rely on my Controller/ViewModel caching the async data.

    Your proposed changes to allow the use of INotifyPropertyChanged, however, sounds ideal. Both for the performance and, as you mention, as a way I can avoid caching the data. I'm already receiving change notifications from my model, so I can merely delay them until the LateUpdate myself.


    One other thing that you have probably mentioned somewhere, but you don't have deep binding path walking, do you? (that is, to say a binding path (on a binding context) of Value.Inventory.Count? It appears to allow Value.Inventory just fine, and due to the direct access to the unity hierarchy, it seems like this is a non-issue. I can either manually walk down the path using nested binding Contexts or refer to a parent object's binding context to walk up. I'm not surprised if you don't support deep binding paths as it is difficult to get it right, and your implementation seems to have a convenient workaround to this issue. I just want to make sure I'm right here and not missing anything.

    Thanks!
     
  12. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    I am glad the information was helpful.

    The current version (V0.1) does support full property path walking when bound to a Binding Context. For your example, Value.Inventory.Count, should work just fine. There is currently no depth limit on the property path.

    Simple Bind does not currently support multi-level property paths when bound to Components other than the Binding Context. However, this feature is in the backlog.
     
  13. RealityDotStop

    RealityDotStop

    Joined:
    Mar 4, 2013
    Posts:
    42
    Ah, yeah, that was my mistake. I was setting the top level binding context to my view model script, but I naively assumed that to get the script itself rather than a child property I should use a path of "None." NOPE! Turns out that is truly none. I had to create a "Self" property in my script:

    public T Self { get { return this; } }

    That wasn't obvious to me and I wouldn't rule out that I missed something, but I wasn't able to find another way to reference it. Works fine now, though!
     
  14. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    PixelHero - could you please provide a little more information about how your binding, view model and hierarchy is setup?

    It should be possible to get the bound object directly without the need to create a "Self" property.
     
  15. RealityDotStop

    RealityDotStop

    Joined:
    Mar 4, 2013
    Posts:
    42
    Sure!

    I'll go into more detail than I think you are asking for to benefit anyone who follows along later.

    I have MVC setup for the existing items. That is-
    • Model - a Unity independent Model that is used at the simulation level. It largely consists of data.
    • Controller - a Controller that knows about both the Model and the View. It knows to, say, play an animation due to data that occurred in the Model. Or it knows to alter the Model's health value because it detected a collision with a projectile.
    • View - That is the actual representation of the Model in the gameworld. It might be a 3d model, it might be a 2d image. In unity, this is your actual gameobject.
    For the purposes of what follows, lets refer to an instance of one of these as an Entity.


    That is all existing in the game. Then I added a UI for an Entity that uses binding. It consists of:

    • A View - This is the actual user interface components. Contains bindings on the viewmodel.
    • a ViewModel - this is used as the datacontext for the View, but it does not actually know how the view is constructed. Contains references to the Controller for data access. Note that the ViewModel doesn't duplicate data, but it does serve as a place to do things like string manipulations, View/ViewModel-only properties and behavior, and respond to user interface interactions to change things in the Entity.
    In my case, my UI contains a "pin" functionality that prevents the window from closing when opening the UI for another Entity. This is useful in debugging, as you can expose AI behaviors and show them change in response to environmental state.

    However, that's a UI View/ViewModel only property. It makes no sense to stuff that in the MVC Entity. So for that Binding, I was binding to a property on the ViewModel, but for other data, I either need to create pass-through properties in my ViewModel to the controller/Model data, or I need to bind into the controller.

    The one I was having trouble with, however, was the "pin" functionality. My viewModel has

    bool Track {get;set;}

    And setting the UI binding context to the ViewModel, I had to use a "self" property in my viewModel in the binding context to allow a bind later to the BindingContext's Value.Track to succeed.
     
  16. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    Thanks for the detailed information.

    I am going to set up a sample project to mimic the behavior that you are looking in order to verify that this works correctly (without the need for the Self property) in the upcoming release.
     
  17. RealityDotStop

    RealityDotStop

    Joined:
    Mar 4, 2013
    Posts:
    42
    Here's a simple test scene with four test cases in a scene in the root assets folder.. I have a simple canvas with a child text object. In the first two cases (which appear on top) have the text box binding to the parent's context, which is set to be the VM script with a path of either "None" (In WPF, this would be the item itself when passing parameters to templated children, etc) or "Self" - a property I gave the VM just so the binding would have something to grab.


    The second two use inheritance.

    I don't see any way to set the datacontext to the VM, other than to use a Self property. Not a problem, really, but this shows what I was trying to do (and if there is some obvious thing I'm missing).

    Hope it helps!

    Note: you must import simplebind v0.1 before loading the scene in the root asset folder.
     

    Attached Files:

    Last edited: Jan 15, 2016
  18. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    Thanks for submitting the test project, it looks similar to the test project I had set up.

    I ran some tests comparing V0.1 with the latest code that will come out in V0.2 and this issue appears to be resolved.

    When viewing the Binding Context while in Play Mode you should see the correct Value displayed in the inspector.

    Using V0.2 I get the following in Play Mode:
    upload_2016-1-13_22-11-26.png

    As you can see when the Path is set to None then the Value is set to the instance of the Component.

    In V0.1 this same test will show a Value of Null.

    I appreciate you posting the test project, but please do not include the SimpleBind asset directly when posting to the forum as this is basically giving away the asset to everyone on the forum. If you could please remove the package from your last post and replace it with a package that only has the test code without the SimpleBind asset it would be greatly appreciated.

    Thanks
     
  19. RealityDotStop

    RealityDotStop

    Joined:
    Mar 4, 2013
    Posts:
    42
    Ah! Whoops! I posted that late at about 3am local time (first night my kid was in a toddler bed), and I was pretty sure I needed to include it since you'd be running a different version. Yeah, I should have thought that through a little more.

    I just removed it for now, I'll upload another one as you suggested later tonight. Sorry! That wasn't my intent.
     
  20. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    No worries. Thanks for updating your post.
     
  21. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    V0.2 has been accepted and released in the Asset Store!

    Simple Bind V0.2 introduces the following new features:
    • Editor context menu integration allowing the creation of Simple Bind Controls directly from the context menu
    • Command class allowing Execute/CanExecute functionality to be easily bound from the View Model to the View
    • Command Button control the fully utilizes the Command class
    • Simple Prefab Editor to simplify View editing
    • Simple Bookmarks to switch quickly between Game Objects within the hierarchy
    • Variety of defect fixes within the core binding classes.
    PixelHero - Please retest the issue you were having with the need for the "Self" property and let me know if the Binding is now working as you would expect (without the need for the "Self" property).
     
  22. RealityDotStop

    RealityDotStop

    Joined:
    Mar 4, 2013
    Posts:
    42
    I haven't had a chance to try out the new Command class or the other new features, but I imported the updated and all four fields are reporting "Worked!" and appears to be Fixed! I'll be able to test some of the other features this weekend, especially since it appears we're getting snowed in with several feet of snow.

    Here's hoping the power doesn't go out!
     
  23. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    Hi, firstly thank you for releasing Simple Bind - I really like the level of features it provides, without being too intrusive and forcing framework choices.

    My colleague and I have found what we think is a bug where Binding Context values set up by ItemsControl on its instantiated child items are being overwritten when the child's Start() method gets called, due to Inheritable.ActivateBinding() thinking it ought to inherit from the parent rather than keep the value provided by ItemsControl.

    I fixed this by adding the following code just before the NotifyPropertyChanged() call in Inheritable.Value.set:

    Code (CSharp):
    1.  
    2.                     if (Binding == null)
    3.                         Binding = new Binding();
    4.  
    This is just enough to prevent Inheritable.ActivateBinding from setting up an inheritance binding.

    It seems to work for us, but we haven't tested it extensively, and I wondered if you had any comments on this fix?
     
  24. Bandrews

    Bandrews

    Joined:
    Jun 8, 2016
    Posts:
    1
    Finding Simple Bind pretty handy, thank you. I do have one question:
    What is an Item Control supposed to do if the list it's based off changes length?
    It appears this change isn't picked up in ItemControl, I believe this is because the List is still the same object so passes the Equals check. I would have expected the Item control to repopulate.

    For example, in the Data Driven Planets videos listed above, could the some planets be removed from the List in the current Map and would this be reflected in the Map's Item Control?
    Thanks.
     
  25. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    gfoot -

    Thanks for your interest in Simple Bind, you have indeed come across a known bug in the current version.

    We have a fix in place and ready to go out with V0.3 (along with several new features and defect fixes).

    Our fix for this problem is slightly different than what you have mentioned.

    Within Inheritable.Start() we applied the below change:

    - ActivateBinding();
    + if (_value == null)
    + {
    + ActivateBinding();
    + }

    This will cause the Binding to be activated only if an initial value was not set. There are several additional changes that have been made to Inheritable to prevent a Binding returning a NULL value from causing inheritance to to override the actual binding.
     
    Last edited: Jun 8, 2016
  26. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    Bandrews -

    Thanks for using Simple Bind, I am glad that you are finding it useful.

    In V0.2 the Items Control will only repopulate if the instance of the List changes, this is not the best approach in most cases and causes a lot of unneeded overhead.

    V0.3 has been submitted for review and includes an Observable Collection (based off the Mono Class Library) that the Items Controls now knows how to work with. When bound to an Observable Collection (instead of a List) the Items control will Add/Remove items as they are added or removed from the bound collection.

    I hope that answers your question. If you need any additional support please let me know.
     
  27. B_Andrews

    B_Andrews

    Joined:
    Jun 27, 2016
    Posts:
    2
    Hi Chad,
    Thanks for the earlier update, the item controls are proving pretty useful.
    I've come across a different issue since, I'm finding that I can't inherit a binding context value.

    Repro steps:
    Create a panel with a pre-defined binding context such as it's color component
    Create a child panel with an empty binding context.
    (I've attached such a scene)

    Result:
    The parent has the expected values in the inspector
    The child panel has inheriting as true but it's value is null.

    Expected result:
    I would expect the child to inherit the parent's context value.

    I'd like to use the feature so that a prefab can refer to it's runtime parent's context, by having an empty context of it's own that would inherit.

    Are there any areas of the code you could point me to?
    ActivateBinding in Inheritable.cs seems to be doing the correct behavior. I noticed the context's _valueSourceEndpoint never really gets set up because the memberAccess can't be built.

    Thanks for any help.
    Ben
     

    Attached Files:

  28. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    B_Andrews,

    Thanks for the feedback, it looks like the problem you are experiencing is a new defect introduced in V0.3. With your provided example scene I was able to track down the issue and have a fix in place for it.

    I'll be adding the fix to the upcoming v0.4 release in a few weeks. If you are interested in patching the version you have please send me an e-mail at unity@sftsrc.com and I can provide you with the files that need updated.

    Thanks,
    Chad
     
  29. squall-leonhart

    squall-leonhart

    Joined:
    May 5, 2017
    Posts:
    26
    Hi Chad,

    First of all sorry for my english.

    Q1 - I have a master Contentcontrol with different views (mostly Dialog boxes). Within some of the views, there's ContentControl too to organize the information relevantly - sort of like a tabcontrol. Due to some of the views
    are DialogBoxes (modal), there's a close button to close the active dialogbox. To do that I pass an Action callback
    in the constructor of dialogbox viewmodel so that master contentcontrol can set the active view to null hence destroying the active dialogbox. It works, I am just wondering if this is the right approach ? Do you have any suggestion ?

    Q2 - to play animation when closing the DialogBox view, I have a Binding Behaviour to bind the property PlayCloseAnimation in the Viewmodel with IsClosing property in the View. Besides that I also has an Event Binding with a string parameter which bind the Closing Animation End event (UnityEvent<string>) to CloseDialog method in the ViewModel. It works with a small issue which is described in Q3, and again I am wondering is this the correct way, seeing it's quite a setup to just play closing animation.

    Q3 - When using Event Binding Behaviour with a string parameter as described in Q2, the CloseDialog method get invoked however the animationName parameter is blank instead of the string passed.

    Code (csharp):
    1.  
    2. public class MainViewModel
    3.     {
    4.         public object ActiveView { get; set; } // Bind contentcontrol path
    5.  
    6.         public Command CmdTestUserInfo { get; set; }
    7.  
    8.         public MainViewModel()
    9.         {
    10.             CmdTestUserInfo = new Command("Test UserInfo", ShowUserInfoDialog, () => true);
    11.         }
    12.  
    13.         private void ShowUserInfoDialog()
    14.         {
    15.             ActiveView = new UserInfoDialogViewModel(CloseUserInfoDialog); // Q1
    16.         }
    17.  
    18.         private void CloseUserInfoDialog()  // Q1
    19.         {
    20.             ActiveView = null;
    21.         }
    22.     }
    23.  
    24. // attach to the view template
    25. public class UserInfoDialogBehaviour : DialogBaseBehaviour
    26.     {
    27.         private bool _isClosing;
    28.  
    29.         public bool IsClosing  // Q2 - Bind to ModelView.PlayCloseAnimation
    30.         {
    31.             get
    32.             {
    33.                 return _isClosing;
    34.             }
    35.             set
    36.             {
    37.                 _isClosing = value;
    38.                 if (_isClosing)
    39.                 {
    40.                     PlayClosingAnimation("UserInfoDialogClosing"); // Q3 - AnimationName passed is "UserInfoDialogClosing"
    41.                 }
    42.             }
    43.         }
    44.     }
    45.  
    46. public class UserInfoDialogViewModel
    47.     {
    48.        public object ActiveView { get; set; } // Bind contentcontrol path
    49.  
    50.         public bool PlayCloseAnimation { get; private set; } // Q2 - Bind to IsClosing in Behaviour/View
    51.        
    52.         // onCloseAction will be invoked from the calling ContentControl ViewModel
    53.         public UserInfoDialogViewModel(Action onCloseAction)
    54.         {
    55.            // bind to a close button
    56.             CmdClose = new Command("", DoClose, () => true);
    57.             _onCloseAction = onCloseAction;  // Q1
    58.         }
    59.  
    60.         /// <summary>
    61.         /// Invoke from CmdClose
    62.         /// </summary>
    63.         private void DoClose()
    64.         {
    65.             ActiveView = null; // clear ContentControl of this Dialog
    66.             PlayCloseAnimation = true;  // Q2 bind to View IsClosing which will run the closing animation...
    67.         }
    68.  
    69.         /// <summary>
    70.         /// Once the close animation finished, this method will be invoked which will invoke the parent ContentControl
    71.         /// ViewModel to set it's Contentcontrol ActiveView to null
    72.         /// </summary>
    73.         /// <param name="motionName"></param>
    74.         public void CloseDialog(string animationName)  // Q2 - Bind to Closing Animation end event
    75.         {
    76.             Debug.Log("CloseDialog.animationName: " + animationName);  // Q3 - animation name is empty ???
    77.  
    78.             if (_onCloseAction != null)
    79.             {
    80.                 _onCloseAction.Invoke();  // Question #1
    81.             }
    82.         }
    83.  
     
    Last edited: Jan 9, 2018
  30. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    squall-leonhart,

    Thanks for your interest in Simple Bind. You have asked some great questions and for good or bad there are multiple ways to implement what you are describing. Which approach is the right approach will come down to the overall architecture for your project.

    Q1 -

    When dealing with Dialogs (or other views that need a centralized manager) I will generally implement a single class that handles showing, overlaying, transitioning and closing those views. In other words I create a DialogManager class which is a MonoBehavior that has access to work on the main UI thread and has all the standard life-cycle hooks needed to control GameObjects, Animations, etc.

    It sounds like you already have something similar to this in the Master ContentControl.

    The key is how do other parts of your application communicate with the DialogManager and how does the DialogManager communicate with the Dialogs that it is managing. Your approach to pass in an action through the constructor of the View Model is an approach I have used at times. It is quick and easy and gets the job done. However, I generally find that allowing the DialogManager to be more loosely coupled to the View Models creates a more flexible design. In order to accomplish this I would create an interface, IClosable, which exposes a Close event and implement IClosable on the ViewModel. This allows the DialogManager to subscribe to the closing of the ViewModel. The key here is that it moves the relationship between the ViewModel and the DialogManager from being tightly coupled (the DialogManager must create the ViewModel) to loosely coupled (the ViewModel can be passed to the DialogManager which then subscribes to the event).

    If your project is utilizing a Signals type pattern for communication you could also use it for this process as well, but Signals come with their own pro's and con's.

    Q2 -

    Playing animation and taking action upon animation events (i.e. animation complete) generally have a bit of setup. In reality your whole chain of events will be something like this:

    Close Button Clicked -> ViewModel notified -> ViewModel sets IsClosing property -> View notified -> View starts animation -> Animation event completes -> View notified -> View raises event to notify ViewModel that closing is complete -> ViewModel notifies DialogManager to close -> dialog finally closed

    There are several ways to short cut this.

    First have the DialogManager handle all closing animation. Since it potentially has access to the View GameObject (depending on your architecture) it can handle calling the appropriate animation logic (either an animation trigger or a call to a specific Component on the GameObject).

    Another approach could be to have a Component on the View that handles the Close Button click, plays the animation, waits for the animation event and then sets the IsClosed property to notify the ViewModel. This reduces the need for the first round trip to the ViewModel to initiate the closing process.

    A large part of this architecture is how fine grained you want your control over the closing sequence, is there validation that needs to occur, does the dialog have to exist in the same content control as other views or can each dialog have its own content control that allows for the animation to be independent of the ViewModel actually closing, can all Dialogs use the same animation, etc.

    Q3 -

    This is currently a limitation in Simple Bind that we have a potential enhancement for (still in testing). Currently, Simple Bind will allow execution of an Event Binding when the source is a UnityEvent, UnityEvent<int> or UnityEvent<string>, however, it will not pass the event parameter through to the bound callback. You can set up static parameters and/or bound parameters to pass to the callback, but not the originating events parameter.

    A work around is to expose the parameter value as a property on the View (or Component that is raising the event) and then bind that value as the first parameter for the Event Binding.

    I hope this helps to answer your questions. If not please let me know.

    Thanks,
    Chad
     
  31. squall-leonhart

    squall-leonhart

    Joined:
    May 5, 2017
    Posts:
    26
    Chad,

    Thanks for your advise and suggestion. It is always good to learn from expert.

    Q1: I plagiarize your IClosable idea :p and get rid of the contrusctor action callback.

    Q2: On the animation, I am leaving it as is because I am using a component based animator which has to be attached to each dialogs and other views (panels) and also because some has different animation. On signaling communication, I do have a simple messenger (Event agrregator - sometimes confuse with the term :D), I use it sparingly mostly on independent/not controllable events because it would become quite messy if overused - maybe it is me not so brilliant :p..

    Actually i am thinking if it is possible to bind a property to the parent DataContext (MasterLayoutViewModel) something like RelativeSource FindAncestor, then things would be easier :rolleyes:, right ?

    Q3: Sure and will heed your advise to bind to a property if need to access the parameter value.

    I hope if you have the time to share some example to do the binding in code or runtime binding possible ?

    Thanks for this great asset. I really enjoying learning and working with it
     
    Last edited: Jan 11, 2018
  32. viktorkadza

    viktorkadza

    Joined:
    Sep 4, 2018
    Posts:
    46
    Hi, does this stuff work with different components,types , like : Image,RectTransform,Color,button,toggle,Textmeshpro ,Transform etc. ?

    regards
    Viktor Kadza
     
  33. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    Viktor,

    Thanks for your interest in Simple Bind. To answer your question, yes, Simple Bind should work with the majority of compenent and property types.

    If you encounter any issues with a particular use case, please let me know.
     
    viktorkadza likes this.
  34. viktorkadza

    viktorkadza

    Joined:
    Sep 4, 2018
    Posts:
    46
    Chad,
    it also can bind custom components, like custom mono-behavior classes?

    regards
    Viktor
     
  35. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    Viktor,

    Absolutely! Simple Bind can bind to custom components and custom property paths within nested objects.

    To learn more about how Simple Bind works and what all it can do, I would suggest watching some of the videos linked in this forum. The videos are older but the the fundamental concepts behind Simple Bind have not changed.

    Thanks,
    Chad
     
  36. moriyanma

    moriyanma

    Joined:
    Jun 9, 2018
    Posts:
    1
    Hello.

    I'm looking for an asset to improve the efficiency of development with Unity.
    I have a question about the operating environment of "Simple Bind".
    Does "Simple Bind" work on WebGL, ie a web browser?
     
  37. chadjriddle

    chadjriddle

    Joined:
    Nov 3, 2014
    Posts:
    18
    Moriyan,

    Apologies on the delayed response. Simple Bind has worked in the past on WebGL, however, we have not fully tested it in the current Unity builds. A lot has changed in Unity over the past year or two which may lead to some issues with Simple Bind and WebGL.

    If you do experience any issue please reach out to us and we will do what we can to resolve any issue.

    Thanks,
    Chad