Is this a bug in the precompiling of Axml?

I have some xaml like so:
<?xml version="1.0" encoding="utf-8" ?>


<ContentView.Resources>


<Setter.Value>

<Grid.RowDefinitions>


</Grid.RowDefinitions>



</Setter.Value>


</ContentView.Resources>

Notice how the SelectedElement and HeaderContainerElement are in the Resources. Here is the output of the g file:

//------------------------------------------------------------------------------
//
// This code was generated by a tool.
// Runtime Version:4.0.30319.34209
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------

namespace Library.Controls {
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

public partial class TabItem : ContentView {

    private Grid HeaderContainterElement;

    private Grid SelectedElement;

    private void InitializeComponent() {
        this.LoadFromXaml(typeof(TabItem));
        HeaderContainterElement = this.FindByName<Grid>("HeaderContainterElement");
        SelectedElement = this.FindByName<Grid>("SelectedElement");
    }
}

}

See how it is creating the properties? These dont actually exist. Is this a defect?

Brad

Posts

  • BradChaseBradChase USMember

    I forgot to put in the ResourceDictionary in that code, but the outcome is the same. Has anyone seen this before?

  • AndrewMobileAndrewMobile USMember ✭✭✭✭

    Can you try format the XAML snippet? It's not complete, I can't see it

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    @BradChase as there was an issue pasting your xaml, I can't say if it's a defect or a feature. In Xamarin.Forms XAML, the ResourceDictionary is not in a different namescope than its parent, and it supports havingm in addition to the x:Key, an x:Name attribute. And all elements in the default Namescope with an x:Name attributes are getting a field in the c# class and that field is initialized at IntitializeComponent () time. AFAIK how to deal with this is not part of the XAML standard and full latitude is left to the implementor.

  • BradChaseBradChase USMember
    edited June 2015

    Yea basically I have a ResourceDictionary in the Resources property of my ContentView. Inside that I have a style that I am initializing the content after the InitializeComponent(). Problem is the elements in that style are being created as properties in the g file on the control. They obviously are not part of that control and just a part of the style in the xaml.

    I can understand why the x:Name would cause it to be seen on the cs side, but maybe its not being seen correctly?

    Trying to get xaml to show up:

        <ContentView xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    xmlns:Controls="clr-Library.Controls;assembly=Library"
                    x:Class="Library.Controls.TabItem">
    <ContentView.Resources>
    
        <ResourceDictionary>
        <Style x:Key="InternalStyle" TargetType="Controls:TabItem" >
            <Setter Property="HeaderContainer">
            <Setter.Value>
                <Grid VerticalOptions="Start" BackgroundColor="Red">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid x:Name="HeaderContainerElement" VerticalOptions="Start"/>
                <Grid x:Name="SelectedElement" BackgroundColor="#20FFFFFF" Grid.Row="1" HeightRequest="2"   VerticalOptions="Start" HorizontalOptions="Fill"/>
                </Grid>
            </Setter.Value>
            </Setter>
        </Style>
        </ResourceDictionary>
    
    </ContentView.Resources>
    </ContentView>
    
  • AndrewMobileAndrewMobile USMember ✭✭✭✭

    can you please update the post with the formatted XAML for clarity
    I think I understand the issue now, but I'm interested to know exactly what you mean

  • BradChaseBradChase USMember

    Andrei, I did but I updated the old post. I should have just posted again, sorry about that confusion.

  • AndrewMobileAndrewMobile USMember ✭✭✭✭
    edited June 2015

    wow, thanks for the update
    I assume you're doing some sort of a templating that's why you need those names
    until the bug is fixed, as a workaround I suggest you do your own attached property which acts like a tag

    if you post the bug, please add a comment with the link, thanks!

  • BradChaseBradChase USMember

    Yea thats exactly what I am doing :). Well I think another way around is how Microsoft does it but loading an external xaml file... I can do that with LoadFromXaml right? and just make a generic.xaml like the old way? I wonder if that is something that will take up too many resources if I were to load that at every file. Maybe I can do a global way and then crawl it for each file in the "OnApplyTemplate()".

    I like the tag idea as well, I actually thought of that once I figured out why it wouldnt compile heh.

    Ill write it up and include the link and copy pastes.

    Brad

  • AndrewMobileAndrewMobile USMember ✭✭✭✭

    I think if you move the Style to Application Resoursources (App.xaml) the problem should go away
    it's not ideal, but will work

    I'm not sure what you're doing exactly, but maybe you could use a DataTemplate
    here's an example http://forums.xamarin.com/discussion/comment/134293/#Comment_134293
    it's not ideal like how a ContentTemplate would be on WIndows but will do the job

  • BradChaseBradChase USMember

    Yea I am familiar with them. In this specific case the DataTemplate just isnt the right choice unfortunately. Since we dont have templating like we had to build controls for wpf/silverlight this will be a temporary work around until I have time to build that functionality in for our program. As of right now, I need to get an example of what our program looks like on the mobile OSs... But its high on my list once we start.

  • BradChaseBradChase USMember

    Just to add, If I was able to declare the control as a custom type in the XAML instead of say a "ContentView" as the base then none of this would be necessary because I could just fill in the property with the Style instead of having to create a custom internal style that I can then apply after init.

  • AndrewMobileAndrewMobile USMember ✭✭✭✭
    edited June 2015
  • BradChaseBradChase USMember

    Haha yes! Thats just about what I was thinking as well. Im wondering if a LoadFromXaml might help get the clutter out of the app xaml?

  • BradChaseBradChase USMember
    edited June 2015

    btw code behind on the temp route I took. Ugly but hey its just a start:

    public void OnApplyTemplate( )
        {
            if( InternalStyle == null )
            {
                Object style = null;
                this.Resources.TryGetValue("InternalStyle", out style);
                if( style != null )
                    InternalStyle = style as Style;
    
            }
    
    
            if( InternalStyle != null )
            {
                foreach( Setter it in InternalStyle.Setters )
                {
                    PropertyInfo prop = this.GetType().GetProperty(it.Property.PropertyName);
                    if( prop != null )
                        prop.SetValue(this, it.Value);
                }
            }
    
            if( HeaderContainer == null )
                throw new Exception("Header Container does not exist.");
    
            _HeaderContainerElement = HeaderContainer.FindByName<Grid>(TabItem.HeaderContainerElement2) as Grid;
    
            if( _HeaderContainerElement == null )
                throw new Exception("Header Container Element does not exist as Grid.");
    
            _IsTemplateLoaded = true;
    
            OnHeaderChanged( );
        }
    

    EDIT: I did this with the InternalStyle so that the control developers can still use Style to override.

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    Thanks for updating your snippet.

    1/ Indeed, the codebehind shouldn't contain references to the Grids
    2/ But it's not an issue, as at the moment the Xaml is instantiated, the Grid exists and is unique
    3/ Also, your style will fail if you try to apply it to multiple TabItem, as Xamarin.Forms styles do not duplicate values. What you need here is a factory, that's usually named a DataTemplate.

  • BradChaseBradChase USMember

    Wow, ok let me understand a few things then. I come from wpf/silverlight so my understanding is in that light. If I create a new TabItem, are you telling me that the Grid in there will be reused for every tab item because it is in that style? Meaning that STYLE and resource dictionary are not created NEW each time that control is created? That would be a bit scary and something I will have to go over.

    Further more, what about the controls inside of that view? If I created new TabItems "ControlViews" each time, then will the contents of those be reused as well?

    Using the current setup they seem to be different controls. Meaning I have the SelectedElement in there binding to an IsSelected property, and of say 5 tabs, only one will show at a time, which is correct. If they were reusing the style's items then they would all either be showing or not showing.

    I understand DataTemplates quite well and this would not be a case to warrant one as each style would only be used ONCE within each control if that is how they render which appears to be correct right now. Maybe I misunderstood that part?

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    Sorry for the misunderstanding.

    Of course, the ResourceDictionary and the Style are created anew everytime you instantiate the control. What I meant was, if you apply the same (instance of) Style to 2 TabItems in the current control, the Value of the Setter won't be duplicated (with only one exception for Binding that we know how to clone).

    If your style is guaranteed to be used ONCE, you're 100% safe, and the bug of having fields declared in your base class is only a little annoyance, and shouldn't block you.

  • BradChaseBradChase USMember

    Ahh yes! ok thanks for that clarification, had me scared for a moment! I do have an issue where I load multiple views and for some reason the data is getting combined from the multiple views but I havent gone through it yet and is most likely my issue there and unrelated to this but got me thinking!

    Sounds like were on the same boat. The controls getting created as of right now is just an annoyance, correct. I had to rename my constants on the cs side because they were named the same but that was about it. I added a '2' to their name for the time being :).

    Thanks for the support everyone!

Sign In or Register to comment.