Search Unity

[RELEASED] XmlLayout: Xml-driven UI Framework

Discussion in 'Assets and Asset Store' started by DaceZA, May 3, 2016.

  1. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174

    XmlLayout
    is a framework for Unity UI which allows you to develop professional, fully functional user interfaces and UI elements using Xml.

    Web GL Demo
    (Including Xml + C# Code for each example, and an example where you can try out your own Xml code)

    Online Documentation
    (Includes a detailed list of tags and attributes)

    ▶ MVVM Documentation

    (Including examples)


    Get it now on the Asset Store!

    Features
    • Utilise all of the functionality of UnityGUI through XML
    • Supports event-handling, on any element (onClick, onMouseEnter, onMouseExit, onValueChanged, etc.)
    • Create and modify elements dynamically at runtime
    • Includes Intellisense/Autocomplete support
    • Set default values to be used by other elements (e.g. visual styles) in a similar fashion to HTML's CSS
    • Easily retrieve form data from multiple elements at once with XmlLayout.GetFormData()
    • Create your own custom attributes
    • Create your own custom element types
    • Includes TableLayout, a layout group based on HTML tables
    • Supports Drag & Drop events
    • Supports both MVC and (new in v1.18) a new (and completely optional) MVVM approach.
    • Supports PagedRect! (Sold Separately)
    • Supports DatePicker! (Sold Separately)
    • Compatible with PC, WebGL, and mobile
    • Full source code included
    Support & Community:

    Join the Reddit community @ /r/XmlLayout/

    Got a question? Found a bug? Have a feature request? Please get in touch with us here, or through our subreddit, or our support e-mail.




    Code (Panel):
    1. <Panel>
    2.      <Text>Text contained within Panel</Text>
    3. </Panel>
    Code (Layout):
    1. <VerticalLayout>
    2.      <Button>Button One</Button>
    3.      <Button>Button Two</Button>
    4.      <Button>Button Three</Button>
    5. </VerticalLayout>
    Code (Table Layout):
    1. <TableLayout>
    2.      <!-- Row 1 -->
    3.      <Row>
    4.          <Cell><Button>Button One</Button></Cell>
    5.          <Cell><Button>Button Two</Button></Cell>
    6.      </Row>
    7.      <!-- Row 2 -->
    8.      <Row>
    9.          <Cell><Button>Button One</Button></Cell>
    10.          <Cell><Button>Button Three</Button></Cell>
    11.      </Row>
    12. </TableLayout>

    Get it now on the Asset Store!
     
    Last edited: Jan 27, 2017
  2. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    V1.01 has been submitted to the asset store, and should be available within the next few days.

    V1.01 brings dynamic XSD generation, so that custom attributes and tags will now automatically have autocomplete/intellisense support added for them!
     
  3. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    V1.08 has been submitted to the asset store and should be available soon!

    Changelist available here
     
    zyzyx likes this.
  4. StevenPicard

    StevenPicard

    Joined:
    Mar 7, 2016
    Posts:
    859
    I am considering purchasing this. I am torn between this and MarkLight. Your table layout is very nice but I do like MarkLight's binding. Currently, with XmlLayout how would I dynamically populate a list, or drop down, or an inventory window with images and information? Would I have to clear the contents and manually loop through a list adding a children control for each item? Also, If the layout scales based on a screen resolution can the contents (text, images, etc.) also scale proportionally if desired? Can 3D obects and particle effects be displayed within the XmlLayout controls?

    I appreciate your time.
     
  5. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi Steven,

    Thanks for your interest in XmlLayout :)

    Currently, with XmlLayout how would I dynamically populate a list, or drop down, or an inventory window with images and information? Would I have to clear the contents and manually loop through a list adding a children control for each item.

    Yes, that is correct. There are several ways in which this could be achieved, although my preferred method has been to create a "template" of the item as an element within the Xml file, and then, for each item, create a duplicate of the template, adjust it as necessary (e.g. set text/color/etc.), and then add the new item. XmlLayout provides a few methods to assist with this sort of thing, e.g. each element (XmlElement) provides an "AddChildElement" method, as well as methods for setting and applying new attribute values. For an examples of how this is done in XmlLayout, you can take a look at the Example Menu (in the LayoutRebuild method) and Options Menu (in the SetFormDefaults method) code.

    It should also be noted that XmlLayout provides a few useful extension methods for elements such as Dropdown.SetOptions(string[] options) and Dropdown.SetSelectedValue(string) to make this sort of thing easier (and if you have any requests for additional methods in XmlLayout, I'd be happy to look into adding them).

    Also, If the layout scales based on a screen resolution can the contents (text, images, etc.) also scale proportionally if desired?

    XmlLayout is rendered by a standard Unity Canvas object, so it can be scaled automatically using the Canvas objects "UI Scale Mode" properties (as with most Unity UI objects). If however, you wish to take more direct control and, for example, have certain objects take up a certain percentage of their parent, then yes, XmlLayout provides this functionality - all Xml Elements have "width" and "height" attributes, which can be set to a specific value, or to a percentage value allowing you set their scale in proportion to their parents. Additionally, TableLayout allows you to set both column widths and row heights, or let TableLayout calculate them for you - so for example, you could set the the width of one or more columns specifically (which will then remain at a constant size), and then the remaining column(s) will have their size calculated automatically (so they will increase or decrease in size depending on how much space is available).

    Also, if you like, TableLayout is available separately from XmlLayout here (although it is probably best paired with XmlLayout, as it was designed with an HTML table approach in mind).

    Can 3D obects and particle effects be displayed within the XmlLayout controls?

    At the moment, no - at least, not without writing a bit of code. However, this is something I could look into adding. Generally displaying 3D objects/etc. within a user interface element requires the use of a RenderTexture and a RawImage, although I see that there may be some new approaches available (see http://forum.unity3d.com/threads/what-is-the-best-way-to-display-3d-models-as-ui-elements.343205/).

    I appreciate your time.

    You're welcome, I hope this helps!
     
  6. StevenPicard

    StevenPicard

    Joined:
    Mar 7, 2016
    Posts:
    859
    Thank you. I appreciate you taking the time to respond.
     
  7. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    I've just released our first video tutorial for XmlLayout!
    You can find it here:

     
    Last edited: Oct 13, 2016
  8. Genom

    Genom

    Joined:
    Dec 2, 2014
    Posts:
    86
    Hi, great concept, I'm just wondering about couple of questions:

    1) You mention mobile, does it means iOS? I mention that because of the way you link with the interal events (eg. onclick="MyMethod();" this way reminds me to dynamic generation and it could not work with AOT

    2) Have you considered and MVVM approach as well as the MVC one? this in one of the good points of the Marklight tool but I prefer much much more yous about exposing directly the Unity UI controls instead of creating a whole new markup language as theirs

    I'll come soon with more questions for sure : )

    regards!
     
  9. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi Genom,

    1) While I haven't personally tested on iOS (I don't own any iOS devices), several of my clients use iOS and it seems to work fine for them. The events are linked to methods through the use of reflection, which to my knowledge, should work fine on any platform.

    2) MVVM is on the list of potential features which I may add in the future, although there's no certainty on that yet. I recently added a localization feature to XmlLayout, and while I was building it, it occurred to me that a similar approach could be used as the starting point for an MVVM feature :)
     
  10. Genom

    Genom

    Joined:
    Dec 2, 2014
    Posts:
    86
    Hi DaceZA, thanks for your fast response : ) normally I would have supposed you are using reflection, what made me hesitate about it was that n the example you use the parenthesis and semi colon "();" while for reflection you just need the name of the method.

    About MVVM yes for sure it would be awesome to have it ^_^, specially for dinamic items (list, tables). Coming back to your examples, you give an id to the controls to access them, while it is not a problem to set a property layer to simulate a view model to mask the code-behind for the predeclared ones in the xml, for those ones invoked dinamically, how would you do it now? giving them a runtime specific id to read the properties (eg. a list of inputfields)?

    My other main question is about UI composition (not an easy thing with current Unity design, where the most decoupled approach is with prefabs). Do you have any way to call/navigate different views and/or include them in a main one? I think I've read something the possibility to creat UserControls but as I've just discovered today your framework, I had no time to read all the documentation.

    By the way, I really like how you handle the styles, it is pretty straightforward, css-style, much better than wpf one

    cheers!
     
  11. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi Genom,

    thanks for your fast response : )

    You're welcome :)

    what made me hesitate about it was that n the example you use the parenthesis and semi colon "();" while for reflection you just need the name of the method.

    Yes - to be honest the parenthesis and semi-colons are completely optional (except when passing an argument, in which case you at least need the parenthesis). I decided to include the option for this format as it is what I am used to from my web development days :)

    My other main question is about UI composition (not an easy thing with current Unity design, where the most decoupled approach is with prefabs). Do you have any way to call/navigate different views and/or include them in a main one? I think I've read something the possibility to creat UserControls but as I've just discovered today your framework, I had no time to read all the documentation.

    Yes, at the moment there are two ways this can be done - the one would be to create a custom element/tag (which allows you to optionally specify a prefab, as well as custom handling of attributes / child elements / etc. so you can control how the element works ).

    The second option would be to create an xml file containing your child view which you can then include in your parent view using the <Include path="" /> tag. XmlLayout will then read the child view as if the Xml it contained were in the parent.

    By the way, I really like how you handle the styles, it is pretty straightforward, css-style, much better than wpf one

    Thanks, I'm glad you like it! I've drawn a lot of inspiration from HTML/etc. when building XmlLayout - I was pleased with how the defaults tag worked out :) In time, I intend to add functionality to them as well (e.g. the ability to style elements by id, etc.)
     
  12. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi everyone,

    I'm pleased to report that XmlLayout now supports an (optional) MVVM approach!

    You can view the new MVVM documentation here:
    http://www.digital-legacy.co.za/XmlLayout/Documentation/MVVM

    This is the first iteration of MVVM in XmlLayout, no doubt it will be added to and improved over time with the help of your feedback!
     
    Genom and StevenPicard like this.
  13. Genom

    Genom

    Joined:
    Dec 2, 2014
    Posts:
    86
    Congratulations! MVVM is the best thing after the coca cola zero : D

    Couple of comments and feedback:

    1) Do you think it is possible use an alternative way to System.Remoting so it can work without problems in webgl and ios/IL2CPP? If you provide a little explanation about how it depends on remoting now maybe we can help to figure out a solution.

    2) I've just tried the latest compilation of unity 5.6.b6 with the mono .Net 4.6 experimental preview together with XmlLayout and it seems to work correctly (with some weird error about Destroying objects that anyway don't stop it working) in Android (mono) and Desktop, but fails with the IL2CPP compilations (iOS, Android, and WebGl -without mvvm I mean). It loads the view, but does not load subviews within.

    cheers and thanks for your work!
     
    Last edited: Feb 5, 2017
  14. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi, thanks!

    1) To be honest, I don't think so, at least not without severely compromising the ease-of-use the new MVVM system provides.

    Remoting is used to create proxies of the ViewModel, as well as items in ObservableLists. These proxies intercept all changes to properties, allowing XmlLayout to react to these changes and update the appropriate elements in the view. As such, it is basically the glue which makes MVVM work - without it, it would be necessary to notify XmlLayout of each property change manually.

    I've tried to see if any third party proxy frameworks (e.g. Castle DynamicProxy) could do, but I haven't found any that are compatible with Mono and Unity.

    I have logged a request with Unity to look into adding the System.Runtime.Remoting namespace in future, but I don't think it would be a very high priority for them, as Remoting is not used all that much compared to most C# functionality - in 9 years of C# programming, I have used Remoting twice. Once when I was studying the language (it was in the curriculum), and now - when implementing XmlLayout.

    2)
    a) I occasionally get the destroyed object error too, in my case it is very infrequent, and when it does happen it is because XmlLayout is interrupted during a layout rebuild/etc. by the editor switching back from play mode to edit mode, where XmlLayout finds that the object it was about to destroy is already gone. I may be able to suppress it at some point by locating all Destroy calls and adding a null check (although in some cases I've seen that even a null check isn't sufficient, as the object can be destroyed after the null check but before the actual Destroy call). In any case, as it is infrequent, and doesn't actually break anything, I haven't worried about it overmuch.
    Is it happening frequently in 5.6b6? Perhaps something has changed that I will need to account for.

    b) When you say it doesn't load subviews, do you mean that the <Include /> tag isn't working?
     
    Last edited: Feb 6, 2017
  15. Genom

    Genom

    Joined:
    Dec 2, 2014
    Posts:
    86
    Hi DaceZA,

    about 1) Maybe with the new 4.6 Remoting will be available, while it doesn't rely on Emit or any dynamic feature or multithreading it will be work both with iOS and Webgl.

    I undestand what you say about easy to use. I've working in a MVVM approach based on reflection and attributes, kind of


    [BindingControlProperty(Controls = new string[] { "UserNameControl" }, Property = BindeableProperties.text, BindingDirection = BindingDirection.TwoWay)]
    public string UserName
    {
    get
    {
    return _userName;
    }
    set
    {
    _userName = value;
    }
    }


    then I have to create sets and watching changes for each control and BindeableProperties (an enum) manually, but it works, and in the end there are not many fields that are needed to bind. I will make an experiment combining your controllers and my Bindeable properties to see how they work together.


    about 2) includes work fine (just a little annoying placing everything in Resources folder), I mean loading by code

    public XmlLayout LoginView;

    void LoginClick()
    {
    var container = xmlLayout.GetElementById<RectTransform>("PanelContainer");
    LoginView.transform.parent = container.gameObject.transform;

    if (CurrentView != null)
    CurrentView.Hide();

    LoginView.Show();
    CurrentView = LoginView;
    }

    I followed one of your examples to do it, assigning LoginView from the editor, I'm wondering how to invoke the xml views without having them attached this way, maybe you can help me to figure it out.

    thanks and regards!
     
  16. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi Genom,

    I've sent you a PM with an example that shows how you can instantiate/access XmlLayout instances purely using code, so that you don't have to set up references in the editor. Hope it helps :)
     
  17. pluralcerog

    pluralcerog

    Joined:
    Feb 28, 2017
    Posts:
    2
    Hi DaceZA,

    I have a little problem with the xml and a style xml with a default tag. I mean i want 4 buttons ordered in a horitzontal layout but the buttons took the width and height from the horitzontal layout ignoring my specific pixels on the style xml. The only way i found to make them use those pixels is using the "ignoreLayout" tag, but i lose the utility of the horizontal layout making me to set to every button an offestXY.

    Here you have the XML layout with the buttons:
    <Panel>
    <VerticalLayout class="VerticalLayout">

    <HorizontalLayout class="HorizontalLayout">
    <Button class="Hl1Button" offsetXY="60 -60" >Almacen</Button>
    <Button class="Hl1Button" offsetXY="544 -60">Carta</Button>
    <Button class="Hl1Button" offsetXY="1027 -60">Mesas</Button>
    <Button class="Hl1Button" offsetXY="1510 -60">Cocina</Button>
    </HorizontalLayout>

    </VerticalLayout>
    <VerticalLayout>

    </VerticalLayout>
    </Panel>

    and here the style XML.

    <Defaults>
    <VerticalLayout class="VerticalLayout1" color="#171c21" padding="0 0 0 0" spacing="0"/>
    <HorizontalLayout class="HorizontalLayout" padding="100 100 100 800" spacing="100"/>
    <Button class="Hl1Button" ignoreLayout="true" color="#6e43b7" rectAlignment="UpperLeft" fontSize="50" height="350" width="350" fontStyle="Bold"></Button>
    </Defaults>

    I include the style XML, and it works that way.

    it's possible to keep the horitzontal organitzation but set my own height and width?
     
  18. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi!

    Yes, you can do this - the default behaviour of most layout groups in Unity is to take direct control of the size of their children, but you can disable this behaviour by using the 'childForceExpandWidth' and 'childForceExpandHeight' attributes, for example:

    Code (CSharp):
    1. <HorizontalLayout childForceExpandWidth="false" childForceExpandHeight="false">
    2.      <Button />
    3.      <Button />
    4.      <Button />
    5.      <Button />
    6. </HorizontalLayout>
    As with most attributes, you can set this in the <Defaults> tag as well if you prefer, e.g.

    Code (CSharp):
    1. <Defaults>
    2.      <HorizontalLayout childForceExpandWidth="false" childForceExpandHeight="false" />
    3. </Defaults>
    ^ This would set these attributes for all HorizontalLayout groups.

    Note: you will also need to use the 'preferredHeight' and 'preferredWidth' attributes on the buttons as Unity Layout Groups don't permit direct changes of element dimensions.

    You can find more information on how flexible widths/heights work in Horizontal Layout Groups here and more information on LayoutElements (which provide attributes such as min width/height, preferred width/height, and flexible width/height) here.

    Hope this helps!
     
  19. pluralcerog

    pluralcerog

    Joined:
    Feb 28, 2017
    Posts:
    2
    Thank you very much! it works perfectly! no more OffsetsXY!
     
  20. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    Hello,

    I found a little problem working with includes, i need to atatch a Controller to the included XML Layout file. I tried to use "getElementByID" to get the component, but it comes null. I think it comes null becouse included files go into the GameObject of the father instead of creating a new Game Object, but debugging with Visual Studio i found an array with included files with the XML that i included. So i guess i'm doing the wrong metodth.

    How i can atatch a controller in a included XML layoute?

    Code (CSharp):
    1. <Include path="Xml/Menu/MenuView.xml" controller="MenuViewController"/>
     
  21. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi,

    I'm afraid that the <Include> tag doesn't work that way - it simply substitutes the Xml from the included file into the parent - it doesn't actually create child XmlLayout objects or anything along those lines.

    If you'd like to create child XmlLayout objects, it can be done, but a little bit of coding will be required.

    For example:

    Main View:

    Code (Xml):
    1. <Panel id="childViewContainer">
    2. </Panel>
    Main XmlLayoutController:


    Code (CSharp):
    1. public override void LayoutRebuilt(ParseXmlResult parseResult)
    2. {
    3.        if (parseResult == ParseXmlResult.Changed)
    4.        {
    5.            LoadChildView();
    6.        }
    7. }
    8.  
    9. private void LoadChildView()
    10. {
    11.      // get a reference to the container
    12.      var container = xmlLayout.GetElementById<RectTransform>("childViewContainer");
    13.  
    14.      // instantiate a new XmlLayout using the XmlLayoutFactory
    15.      var childXmlLayout = XmlLayoutFactory.Instantiate(container, "Path/To/Child/View", typeof(YourXmlLayoutControllerType));
    16. }
    I'll look into adding a functionality to handle this automatically for future versions of XmlLayout.

    I hope this helps!
     
  22. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    I've just added the 'ChildXmlLayout' tag to XmlLayout, and it will be available for future versions.

    If you'd like, you can add it to your project by adding the this Tag handler to your project (it doesn't really matter where in your project you put it, but the default location for official XmlLayout tags is "UI/XmlLayout/Tags").

    Usage:

    Code (Xml):
    1. <ChildXmlLayout viewPath="Path/To/View/Xml" controller="ControllerTypeName" />
    Note: if your controller is in a namespace, then you should use the full type name e.g. MyNamespace.MyControllerTypeName

    http://pastebin.com/C0yR2kpW

    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine.UI;
    6.  
    7. namespace UI.Xml.Tags
    8. {
    9.     public class ChildXmlLayoutTagHandler : ElementTagHandler
    10.     {
    11.         public override MonoBehaviour primaryComponent
    12.         {
    13.             get { return currentInstanceTransform.GetComponentInChildren<XmlLayout>(); }
    14.         }
    15.  
    16.         // don't use a prefab
    17.         public override string prefabPath
    18.         {
    19.             get { return null; }
    20.         }
    21.  
    22.         // Generate xsd documentation for this
    23.         public override bool isCustomElement
    24.         {
    25.             get { return true; }
    26.         }
    27.                
    28.         // No children permitted
    29.         public override string elementChildType
    30.         {
    31.             get { return null; }
    32.         }              
    33.  
    34.         public override Dictionary<string, string> attributes
    35.         {
    36.             get
    37.             {
    38.                 return new Dictionary<string, string>()
    39.                 {
    40.                     {"viewPath", "xs:string"},
    41.                     {"controller", "xs:string"}
    42.                 };
    43.             }
    44.         }
    45.  
    46.         public override void ApplyAttributes(AttributeDictionary attributesToApply)
    47.         {
    48.             // necessary for elements which don't use a prefab
    49.             MatchParentDimensions();
    50.  
    51.             currentXmlElement.name = "ChildXmlLayout";
    52.  
    53.             base.ApplyAttributes(attributesToApply);
    54.  
    55.             var viewPath = attributesToApply.GetValue<string>("viewPath");          
    56.  
    57.             if (String.IsNullOrEmpty(viewPath))
    58.             {
    59.                 Debug.LogWarning("[XmlLayout][Warning][ChildXmlLayout]:: The 'viewPath' attribute is required.");
    60.                 return;
    61.             }
    62.                            
    63.             Type controllerType = null;
    64.             var controllerTypeName = attributesToApply.GetValue<string>("controller");
    65.  
    66.             if (!String.IsNullOrEmpty(controllerTypeName))
    67.             {
    68.                 controllerType = Type.GetType(controllerTypeName, false, true);
    69.             }
    70.  
    71.             XmlLayoutFactory.Instantiate(currentInstanceTransform, viewPath, controllerType);                      
    72.         }
    73.     }
    74. }
     
  23. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    Thanks a Lot

    I will try this metoth for the moment ,and will wait for new adding.

    EDIT: i just post at the same time than you, now i see your response, i will try it, but probably i will wait till the next version to add it to my project, but i will try this!

    Thanks again!
     
    Last edited: Mar 3, 2017
  24. vvorel

    vvorel

    Joined:
    Jan 31, 2017
    Posts:
    1
    Hello. I would like to ask for advice.
    I am creating a one-way MVVM interface. There is a VerticalScrollView with TableLayout inside with List and Row inside. The List is populated with 600 items. Whenever the VerticalScrollView is turned active, the game starts to run extremely slow (e.g., almost a second for game update).
    Removing the entire Update() function from UIController do not help. No code touches this class during a game update.
    So:
    • Is this normal with that many items, or should I search for something wrong here?
    • If this is normal, is there a way to turn off the slow processes that have no effect?
    Thank you very much!
    Vojta
     
  25. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi Vojta,

    While 600 items is quite a large number, it shouldn't cause any slowdowns (other than creating the 600 items in the first place). However, there were some performance issues in some of the XmlLayout layout groups that were started in Unity 5.5 (something changed in the internal Unity Layout code which was triggering unnecessary layout rebuilds). However, this was fixed in XmlLayout v1.24 (and improved upon in v1.25).

    May I ask, what version of XmlLayout are you using? And which version of Unity?

    Here's a test I did to see how it would handle 600 fairly simple items:

    View:

    Code (Xml):
    1. <XmlLayout xmlns="http://www.w3schools.com"
    2.            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3.            xsi:noNamespaceSchemaLocation="UI/XmlLayout/Configuration/XmlLayout.xsd">
    4.  
    5.   <VerticalScrollView>
    6.     <TableLayout autoCalculateHeight="1">
    7.       <List vm-dataSource="myItems">
    8.         <Row preferredHeight="32">
    9.           <Cell>
    10.             <Text text="{myItems.text1}" />
    11.           </Cell>
    12.           <Cell>
    13.             <Text text="{myItems.text2}" />
    14.           </Cell>
    15.           <Cell>
    16.             <Text text="{myItems.text3}" />
    17.           </Cell>
    18.         </Row>
    19.       </List>
    20.     </TableLayout>
    21.   </VerticalScrollView>
    22.  
    23. </XmlLayout>
    Controller/Model:


    Code (CSharp):
    1. class NewXmlLayoutController : XmlLayoutController<MyViewModel>
    2. {      
    3.     protected override void PrepopulateViewModelData()
    4.     {
    5.         viewModel.myItems = new ObservableList<MyViewModel.myItemType>();
    6.  
    7.         for (var x = 0; x < 600; x++)
    8.         {
    9.             var text = "Item " + x;
    10.  
    11.             viewModel.myItems.Add(new MyViewModel.myItemType
    12.             {
    13.                 text1 = text,
    14.                 text2 = text,
    15.                 text3 = text
    16.             });
    17.         }      
    18.     }  
    19. }
    20.  
    21. class MyViewModel : XmlLayoutViewModel
    22. {
    23.     public ObservableList<myItemType> myItems { get; set; }
    24.  
    25.     public class myItemType
    26.     {
    27.         public string text1 { get; set; }
    28.         public string text2 { get; set; }
    29.         public string text3 { get; set; }
    30.     }
    31. }
    The end result seemed to work fine, other than the initial hit of creating 600 rows at once.

    I'm going to send you a copy of the latest version of XmlLayout (which isn't available in the store yet), perhaps it will help.

    EDIT: I see that Unity has released XmlLayout v1.26 on the store, which is the latest stable version - I've already sent it to you, but you can also just update from the Asset Store if you haven't already.
     
  26. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    • Hello again

    Sorry by lot of questions but i ma trying your last code but i have problem vith " MatchParentDimensions();" does not exist in the current version after update last version of course
    Tahnks for your attention.
     
  27. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Oops, sorry about that - I added that method to ElementTagHandler today and didn't think about it when I gave you that code - here's the definition for MatchParentDimensions():

    Code (CSharp):
    1. protected void MatchParentDimensions()
    2. {
    3.      var parent = currentInstanceTransform.parent as RectTransform;
    4.                    
    5.      currentInstanceTransform.localPosition = Vector3.zero;
    6.      currentInstanceTransform.anchorMin = Vector2.zero;
    7.      currentInstanceTransform.anchorMax = Vector2.one;
    8.      currentInstanceTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, parent.rect.width);
    9.      currentInstanceTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, parent.rect.height);
    10. }
    You can add this to ElementTagHandler.cs (which is where it will be in future versions of XmlLayout), or you can just add it directly to ChildXmlLayoutTagHandler.
     
  28. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    Hello,

    I have another question using the new tag "ChildXmlLayout". When i Use the tag it creates an XmlLayout component but the property xml file it's empty, so it doesnt show me the XML included when i run Unity, but if i drop manually the XML it shows.

    Let me explain a bit more:
    i need to do this drop by code like this (done in your method to test, look edited part):

    Code (CSharp):
    1.  
    2. public override void ApplyAttributes(AttributeDictionary attributesToApply)
    3.         {
    4.             // necessary for elements which don't use a prefab
    5.             MatchParentDimensions();
    6.  
    7.             currentXmlElement.name = "ChildXmlLayout";
    8.  
    9.             base.ApplyAttributes(attributesToApply);
    10.  
    11.             var viewPath = attributesToApply.GetValue<string>("viewPath");
    12.  
    13.             if (String.IsNullOrEmpty(viewPath))
    14.             {
    15.                 Debug.LogWarning("[XmlLayout][Warning][ChildXmlLayout]:: The 'viewPath' attribute is required.");
    16.                 return;
    17.             }
    18.  
    19.             Type controllerType = null;
    20.             var controllerTypeName = attributesToApply.GetValue<string>("controller");
    21.  
    22.             if (!String.IsNullOrEmpty(controllerTypeName))
    23.             {
    24.                 controllerType = Type.GetType(controllerTypeName, false, true);
    25.             }
    26.  
    27.             XmlLayoutFactory.Instantiate(currentInstanceTransform, viewPath, controllerType);
    28.  
    29.             // Edited part
    30.             TextAsset bindata = new TextAsset();
    31.             bindata = Resources.Load(viewPath) as TextAsset;
    32.             currentInstanceTransform.GetComponent<XmlLayout>().XmlFile = bindata;
    33.             ////
    34.         }
    You can see that i'm trying to create an TextAsset with the XML, but it don't work, it comes null every time, i guess it's becouse all the Resources folders that we can create. Anyway i still don't know if this is the correct way to make this drop by code.

    All this effort its to make the ChildXmlLayout like an include but with controller, Any Idea?

    Thanks, and sorry for ask too much!
     
  29. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi!

    The only reason I can think of for the 'Xml File' property to be null is if the 'viewPath' attribute has an incorrect value (I see that it doesn't show a warning for this; I'll add one).

    What value have you provided for the 'viewPath' attribute?
    Looking at the folder structure in your screenshot, it should probably be:

    "Xml/Menu/MenuView"

    Is that the value you are using? Basically, your ChildLayout tag should look as follows

    Code (Xml):
    1. <ChildLayout viewPath="Xml/Menu/MenuView" controller="Full_Name_Of_Your_Controller_Class" />
    It shouldn't be necessary for you to manually set the Xml file of the child layout, but if it does come to that, then a) the file should not be null (which I suspect it is in the code above), and b) you should call the 'ReloadXmlFile()' method after changing it, e.g.

    Code (CSharp):
    1. xmlLayoutInstance.XmlFile = myXmlFile;
    2. xmlLayoutInstance.ReloadXmlFile();
    Here's a working example of this in action - this instantiates one of the layouts used in the demo:

    Code (Xml):
    1. <ChildXmlLayout viewPath="Xml/CurrencyOverlay" controller="UI.Xml.Examples.XmlLayout_Example_CurrencyOverlay" />


    One further note, as of v1.23, you can create custom asset folders instead of using resource folders if you like, although this is completely optional, resource folders will continue to work if you'd prefer to use them. More information is available here: http://www.digital-legacy.co.za/XmlLayout/Documentation#CreatingcustomXmlLayoutResourceDatabases
     
  30. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    Hi hi,

    Thanks for the info, now it works. But now I guess i found a bug. Let me explain deeper.

    Code (CSharp):
    1.             var newView = XmlLayoutFactory.Instantiate(NC1, "Xml/MaterialManagment/MaterialManagementView", typeof(MaterialManagementViewController));
    2.  
    It instanciate the Controller two times, to solve it i had to do this:

    Code (CSharp):
    1. public override void LayoutRebuilt(ParseXmlResult parseResult)
    2.     {
    3.         base.LayoutRebuilt(parseResult);
    4.         NC1 = xmlLayout.GetElementById<RectTransform>("NC1");
    5.  
    6.         var all = this.gameObject.GetComponentsInChildren<MenuViewController>();
    7.  
    8.         all[0].gameObject.name = "xmlLayout1";
    9.         all[1].gameObject.name = "xmlLayout2";
    10.  
    11.         menuViewController = all[1];
    12.         menuViewController.NC1 = this.NC1;
    As you can see when i get the components MenuViewController it gets 2 of them, making test in Unity the name of the XMLLayout changes from "XmlLayoute, to XmlLayoute2 ignoring the rename to xmlLayout1. When i debug with visual studio in this breaking point:

    Code (CSharp):
    1.  public XmlLayout CurrentView { get; set; }
    2.  
    3.     public override void LayoutRebuilt(ParseXmlResult parseResult)
    4.     {
    5.         //base.LayoutRebuilt(parseResult);
    6.         CurrentView = xmlLayout;
    7.     }
    I discover this becouse the breaking point works two times, some properties pass null (becouse there is two controllers) and in the tree of Unity shows only one, and as i said before, the all variable change the name to the xmllayoute 2, so i guess in some place the controller was created twice.

    This also happens withc child tag, probably becouse the child tag do the factory aswell.

    If you need more data, tell me and i can send you more info or the files.

    cheers.
     
  31. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi,

    I can't seem to duplicate this problem with any of my tests, can you send me the files please?
     
  32. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    Hello DaceZA

    I´m try this code but not works otherwise the commented code is working but not is very good.code
    The problem i think is that the onclick is not captured
    Code (CSharp):
    1.  <Button preferredHeight="80"  preferredWidth="300" color="#00000000" onClick="LoadDeliveriesView()">
    2.       <HorizontalLayout childForceExpandWidth="false" childForceExpandHeight="false" padding="0 0 20 0">
    3.         <Text alignment="MiddleLeft" preferredHeight="40"  preferredWidth="270" fontSize="30" fontStyle="Bold" color="#ffffff">
    4.           Albaranes
    5.         </Text>
    6.         <Image   preferredHeight="40"  preferredWidth="40" image="UI - BUILDER\Source Files\Icons\Icons@2x-assets\App\AppIcons_7" rotation="0 0 0" color="#ffffff"></Image>
    7.       </HorizontalLayout>
    8.     </Button>
    9.  
    10.     <!--<Panel preferredHeight="80"  preferredWidth="300" color="#00000000">
    11.       <HorizontalLayout childForceExpandWidth="false" childForceExpandHeight="false" padding="0 0 20 0">
    12.         <Text alignment="MiddleLeft" preferredHeight="40"  preferredWidth="270" fontSize="30" fontStyle="Bold" color="#ffffff" >
    13.           Albaranes
    14.         </Text>
    15.         <Image   preferredHeight="40"  preferredWidth="40" image="UI - BUILDER\Source Files\Icons\Icons@2x-assets\App\AppIcons_7" rotation="0 0 0" color="#ffffff" raycastTarget="false"></Image>
    16.       </HorizontalLayout>
    17.       <Button preferredHeight="80"  preferredWidth="300" color="#00000000" onClick="LoadDeliveriesView()">
    18.       </Button>
    19.     </Panel>-->
    there are somethink about "raycastTarget" but is only for image.
    Whats is your opinion of this code
    Lot of tanks

    Salutations
     
  33. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    An aclaration
    The really problem is that the button onclic dosen´t works
    Salutations
     
  34. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi,

    The onClick works for me so long as I don't click on the image (as images block raycasts by default, but you can prevent this by setting its raycastTarget value to false, e.g.

    Code (CSharp):
    1. <Button preferredHeight="80"  preferredWidth="300" color="#00000000" onClick="LoadDeliveriesView()">
    2.     <HorizontalLayout childForceExpandWidth="false" childForceExpandHeight="false" padding="0 0 20 0">
    3.       <Text alignment="MiddleLeft" preferredHeight="40"  preferredWidth="270" fontSize="30" fontStyle="Bold" color="#ffffff">
    4.         Albaranes
    5.       </Text>
    6.       <Image   preferredHeight="40"  preferredWidth="40" image="UI - BUILDER\Source Files\Icons\Icons@2x-assets\App\AppIcons_7" rotation="0 0 0" color="#ffffff" raycastTarget="false"></Image>
    7.     </HorizontalLayout>
    8.   </Button>
    I must admit though, I am surprised that this code works at all - the <Button> element was never really intended to support having child elements (you'll see that the Xml validator picks it up as an issue).

    Is there a reason why you're not using the <Button> elements built-in icon? For example:

    Code (CSharp):
    1. <Button preferredHeight="80" preferredWidth="300"      
    2.           color="#00000000"
    3.           onClick="LoadDeliveriesView()"
    4.           textAlignment="MiddleLeft" textColor="#ffffff"
    5.           fontSize="30" fontStyle="Bold"
    6.           icon="UI - BUILDER\Source Files\Icons\Icons@2x-assets\App\AppIcons_7" iconAlignment="Right" iconWidth="40" iconColor="#ffffff">Albaranes</Button>
    Note: you can use the also "padding" attribute if you'd like to adjust the position of the text/icon.
     
  35. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    Lot of thanks

    I use now your clean code
     
  36. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    Hello

    I have this mistake and i not have the autocomplete Intellisense
    in a
    xsi:noNamespaceSchemaLocation="../../../../Components/UI/XmlLayout/Configuration/XmlLayout.xsd">
    cound

    May be the folderframe are not correct

    What do you think about this, have you an a idea ?
    Thanks for your attention
     
  37. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi,

    That path depends on where the Xml file itself is located, it is a relative path between the Xml file and the xsd file which provides the autocomplete functionality.

    For example, if your Xml file is in the following location in your Assets folder:

    Example/Path/MyXmlFile.xml

    And you've placed XmlLayout in Components/UI/XmlLayout,

    Then the correct path value for noNamespaceSchemaLocation would be:

    ../../Components/UI/XmlLayout/Configuration/XmlLayout.xsd

    (../ basically means move up one directory, so we go up two directories, and then descend into the XmlLayout installation to locate the autocomplete file 'XmlLayout.xsd').

    XmlLayout will automatically populate this path for you in new Xml files based on the location where they are created, but once they have been moved you may need to update the value yourself.
     
  38. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    sorry my message is incomplette
    in a
    xsi:noNamespaceSchemaLocation="../../../../Components/UI/XmlLayout/Configuration/XmlLayout.xsd">

    i have a mistake like this

    could not not find the path .C:\Development\Unity\DelicappPro2\Assets\Views\Components/UI/XmlLayout/Configuration/XmlLayout.xsd
    but this path of popup path not exist
     
  39. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi, looking at that error message, the correct value for noNamespaceSchemaLocation should be:

    ../../../../../Components/UI/XmlLayout/Configuration/XmlLayout.xsd

    as the correct (absolute) path is:

    .C:\Development\Unity\DelicappPro2\Assets\Components\UI\XmlLayout\Configuration\XmlLayout.xsd

    Which is one directory higher than where it is looking currently. Basically, the path should be ../ (up one directory) until we reach the Assets/ directory, and then down into the XmlLayout directories to locate the file.
     
  40. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    My tree folder is :
    C:\Development\Unity\DelicappPro2\Assets\Components\UI\XmlLayout\Configuration/XmlLayout.xsd"

    but path go to find it in C:\Development\Unity\DelicappPro2\Assets\Views\Components/UI/XmlLayout/Configuration/XmlLayout.xsd

    Components folder are not in wiews , are in under assets
     
  41. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi,

    Please try changing:

    xsi:noNamespaceSchemaLocation="../../../../Components/UI/XmlLayout/Configuration/XmlLayout.xsd"

    to:

    xsi:noNamespaceSchemaLocation="../../../../../Components/UI/XmlLayout/Configuration/XmlLayout.xsd"
     
  42. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    I try this ../../../../../Components/UI/XmlLayout/Configuration/XmlLayout.xsd
    but not work the message now is "the eschema referenced from this location in your document contains errors"
     
  43. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Are you using the latest version of XmlLayout (v1.28)?

    Have you implemented any custom attributes or element tag handlers?
     
  44. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    this is the xml path C:\Development\Unity\DelicappPro2\Assets\Views\Resources\Xml\MaterialManagement\Articles

    and i think taht will be ../../../Components/UI/XmlLayout/Configuration/XmlLayout.xsd

    folulder resources not count no?
     
  45. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    No, in this case this is a path used strictly by Visual Studio, not Unity. The path you tried last was correct, as it has to have located the file in order to have shown that error message.
     
  46. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    Actuallly i use a modified version, if you remember some days ago, you send me how to add, childLayoute tagg.
     
  47. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    I try to update

    Thanks
     
  48. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    As of v1.27 the ChildLayout tag is now included in the main XmlLayout package - if you update to 1.28 (the latest available version) and remove your custom ChildLayout tag handler, it might solve the issue you're experiencing. Let me know :)
     
  49. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
  50. ricardMilo

    ricardMilo

    Joined:
    Mar 3, 2017
    Posts:
    17
    Hello

    Updating to 1.28 the poblem was resolt

    Lot of thanks