Microsoft Developer Network > Domovská stránka fór > Windows Presentation Foundation (WPF) > How to get x:Name from 3DElements using XamlReader.Load
Odeslat dotazOdeslat dotaz
 

OdpovědětHow to get x:Name from 3DElements using XamlReader.Load

  • 13. června 2009 13:12matzeooK Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     

    I would like to get all Names from DependencyObject- Elements in my Viewport3D. As we know: none of the 3D Elements has a Name Property, so x:Name is used for instance description.
    How can I resolve the x:Name for every Element in my 3D tree?

    A nice Trick to locate the name of an 3DElement is to get all Fields that where generated for the x:Names:
    FieldInfo[] fieldInfos = rootElement.GetType().GetFields( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    And then compare the object thats given back from FindName(fieldInfo.Name) with all 3DElements in tree. Something like this:
    foreach (FieldInfo info in fieldInfos)
    {
      if(compareDepObj == FindName(info.Name))
         compareDepObjHasNameInfoName 

    }

    This works fine when I load a compiled UserControl assembly. But when I use XamlReader.Load/Parse I could not find any of the x:Name Fields.
    I think they must be there because a FindName(X:NAME) always works. And Documentation for x:Name says:
    "x:Name is used by a XAML processor to register a name into a namescope, even for cases where the page is not compiled (for instance, loose XAML)."
    Do I use the wrong BindingFlags?
    Has anybody an Idea?



    ooK

Odpovědi

  • 19. června 2009 10:20Rob RelyeaModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Odpovědět
    Compiled XAML or XAML will attempt to register all x:Names (or Names on classes which have declared it their special name property via [RuntimeNamePropertyAttribute] (like FrameworkElement does) with the nearest namescope.
    Compilation of XAML creates the fields.

    So what you are seeing is expected.  When you use XamlReader.Load, there are no fields, since you didn't compile the XAML. However, findName still works.

    One solution for this is to make your root element implement INameScope.  You can then iterate through the list, since you own it.

    In .NET 4, your scenario could get a bit easier, as you could write a custom XAML node loop and understand all names and the objects they map to.  Perhaps I should write a quick sample for that...

    Thanks, Rob Relyea
    WPF/XAML Team
    http://robrelyea.com/blog
  • 23. června 2009 11:30Rob RelyeaModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Odpovědět
    I've posted a sample using .NET 4 beta 1 on my blog: "XAML node loop example: finding all named object instances"

    Thanks, Rob
    • Označen jako odpověďmatzeooK 29. června 2009 9:43
    •  
  • 20. října 2009 0:55Rob RelyeaModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Odpovědět

    E.-
    Try this:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Markup;

    namespace WindowWithNameScope
    {
        //This class, if placed at the root of a XAML file which is loaded by XamlReader.Load()
        //will end up having all named elements contained in its nameTable automatically...
        //
        //If you want to get that list, it is now in your power.
        public class WindowWithNameScope : Window, INameScope
        {
           
            Dictionary<string, object> nameTable = new Dictionary<string, object>();

            object INameScope.FindName(string name)
            {
                object element = null;
                nameTable.TryGetValue(name, out element);
                return element;
            }

            void INameScope.RegisterName(string name, object scopedElement)
            {
                nameTable[name] = scopedElement;
            }

            void INameScope.UnregisterName(string name)
            {
                nameTable[name] = null;
            }
        }
    }

    Hope that helps... (I didn't test this, let me know if it doesn't work, and I'll go do that...)
    Thanks, Rob

Všechny reakce

  • 19. června 2009 10:20Rob RelyeaModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Odpovědět
    Compiled XAML or XAML will attempt to register all x:Names (or Names on classes which have declared it their special name property via [RuntimeNamePropertyAttribute] (like FrameworkElement does) with the nearest namescope.
    Compilation of XAML creates the fields.

    So what you are seeing is expected.  When you use XamlReader.Load, there are no fields, since you didn't compile the XAML. However, findName still works.

    One solution for this is to make your root element implement INameScope.  You can then iterate through the list, since you own it.

    In .NET 4, your scenario could get a bit easier, as you could write a custom XAML node loop and understand all names and the objects they map to.  Perhaps I should write a quick sample for that...

    Thanks, Rob Relyea
    WPF/XAML Team
    http://robrelyea.com/blog
  • 23. června 2009 11:30Rob RelyeaModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Odpovědět
    I've posted a sample using .NET 4 beta 1 on my blog: "XAML node loop example: finding all named object instances"

    Thanks, Rob
    • Označen jako odpověďmatzeooK 29. června 2009 9:43
    •  
  • 29. června 2009 9:50matzeooK Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    thank you Rob!
    Until I can use .NET 4 Release I search all my x:Names using XML SelectNode.
    Thank you for the nice sample in your Blog.
    ooK
  • 15. října 2009 16:38EeeeEfff Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    I'm glad I came across this post, as I've been trying to do the same thing and bumping against this problem for a few days now.  

    I like the .Net 4.0 solution, but it is not really something I can use at this point in time.  So, in order for me to build a TreeView of my XAML 3D model, do I really have to resort to reading the XAML a second time, searching for x:Names using XML SelectNode?  Does not sound like the right way to go - some of my XAML model files are 300+MB...

    You mentioned "One solution for this is to make your root element implement INameScope.  You can then iterate through the list, since you own it."  I'm not sure I understand how this would work.  My root element is the Window which contains the Viewport3D.  Are you suggesting to implement INameScope in the Window, and call INameScope.RegisterName to add each Visual3D elements to the Window's namescope?  And that would somehow allow me to get the Visual3D element's name?

    How does Expression Blend display the tree (including the element names) when a XAML 3D file is loaded?  Does it compile it?  Is there some way for me to compile my XAML file as I'm importing it, in order to get the field names??

    Thanks for any insight.
    E.

  • 16. října 2009 16:50Rob RelyeaModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    E.-
    If you built a MyWindow class:

    public class MyWindow : Window, INameScope
    {
    ...
    }

    <l:MyWindow x:Class="MyWindow1">
    ...
    </l:MyWindow>

    In .Net 3 and later, the XAML parser will call INameScope.RegisterName passing in the name and object instance.  So this, if it is an option, is an elegant way to do it that works in v3 and v4.

    Blend displays element names because they effectively have their own XAML parser, and can see the names before they are created...easily being able to coorelate the names to the eventual instances...

    Hope that helps.
    -Rob

  • 19. října 2009 15:09EeeeEfff Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Obsahuje kód
    Thanks so much for responding, Rob!

    Based on your suggestion, here is what I did:
    In my window base class, WindowBase, I implemented INameScope (implementation below).  I had to implement a helper method (my own GetNameScope), because by default, I was getting null when I called NameScope.GetNameScope(this);

            #region INameScope Members
    
            object System.Windows.Markup.INameScope.FindName(string name) {
                INameScope scope = GetNameScope();
    
                return null != scope ? scope.FindName(name) : null;
            }
    
            void System.Windows.Markup.INameScope.RegisterName(string name, object scopedElement) {
                INameScope scope = GetNameScope();
    
                if (null != scope)
                    scope.RegisterName(name, scopedElement);
            }
    
            void System.Windows.Markup.INameScope.UnregisterName(string name) {
                INameScope scope = GetNameScope();
    
                if (null != scope)
                    scope.UnregisterName(name);
            }
    
            #endregion
    
            #region GetNameScope_Helper
    
            protected INameScope GetNameScope() {
                //return NameScope.GetNameScope(this); // returns null, unless I create my own...?
                DependencyObject element = this;
    
                while (null != element) {
                    INameScope nameScope = NameScope.GetNameScope(element);
    
                    if (null != nameScope)
                        return nameScope;
    
                    element = LogicalTreeHelper.GetParent(element) ?? VisualTreeHelper.GetParent(element);
                }
    
                if (savedScope == null) {
                    savedScope = new NameScope();
                }
    
                return savedScope; 
            }
            #endregion // GetNameScope_Helper
    
    

    Then, once I imported my XAML 3D file, to register, say my viewport object, I would do the following:
    NameScope.SetNameScope(view3D, GetNameScope());
    But that wouldn't add the view3D to the namescope (the default namescope was null, and even when I created my own namescope, view3D was not being added).  So I added the following call to do so:
            RegisterName(view3D.Name, view3D);

    That added the the view3D object to the namescope, but that kinda defeats the purpose, as I will not have the names of all the elements a priori to add them explicitely.  Am I missing something?

    Thanks so much!
    E.



  • 20. října 2009 0:55Rob RelyeaModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Odpovědět

    E.-
    Try this:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Markup;

    namespace WindowWithNameScope
    {
        //This class, if placed at the root of a XAML file which is loaded by XamlReader.Load()
        //will end up having all named elements contained in its nameTable automatically...
        //
        //If you want to get that list, it is now in your power.
        public class WindowWithNameScope : Window, INameScope
        {
           
            Dictionary<string, object> nameTable = new Dictionary<string, object>();

            object INameScope.FindName(string name)
            {
                object element = null;
                nameTable.TryGetValue(name, out element);
                return element;
            }

            void INameScope.RegisterName(string name, object scopedElement)
            {
                nameTable[name] = scopedElement;
            }

            void INameScope.UnregisterName(string name)
            {
                nameTable[name] = null;
            }
        }
    }

    Hope that helps... (I didn't test this, let me know if it doesn't work, and I'll go do that...)
    Thanks, Rob

  • 20. října 2009 6:07EeeeEfff Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Obsahuje kód
    Hi again, Rob; thanks for the suggestion.

    I tried your setup above: 
      public class WindowWithNameScope : Window, INameScope {
        ...
      }

    Then, I created a Window1.xaml + cs: 
    .XAML:
      <LoadXAML3D:WindowWithNameScope x:Class="LoadXAML3D.Window1"
      ...
      </LoadXAML3D:WindowWithNameScope>
    & .cs
      public partial class Window1 : WindowWithNameScope {
        ...
      }

    Window1 has a browse button:
      <Button Width="65" Content="Browse" VerticalAlignment="Center" Margin="4,0,0,0" Click="Browse_Click"/>

    In the button event handler, I loaded the XAML file (bottom of this message) as follows, and added the resulting Viewport3D to a Border.Child in Window1:
                FileStream fs = File.OpenRead(fileName);
                Viewport3D view3D = (Viewport3D)System.Windows.Markup.XamlReader.Load(fs);

    The viewport displays the model, but none of the named entities in the XAML file make it into the nameTable (or trigger the RegisterName method).

    Your comment in the previous post says: "This class, if placed at the root of a XAML file which is loaded by XamlReader.Load()..."
    Do you mean that the XAML file that I am dynamically loading should have "WindowWithNameScope" as the root of that document, in order for this setup to work?

    Thanks so much.
    E.

    Sample (abbreviated) 3D file: none of the named elements are added to the namescope.

    <Viewport3D x:Name="RootViewport3D"
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    	mc:Ignorable="d">
    	<Viewport3D.Camera>
    		<PerspectiveCamera FieldOfView="45" FarPlaneDistance="452.66506021275518" LookDirection="25.151,-7.26,-12.543" NearPlaneDistance="0.1" Position="-25.151,8.363,12.543" UpDirection="0.226,0.969,-0.108"/>
    	</Viewport3D.Camera>
    	<ModelVisual3D x:Name="World">
    		<ModelVisual3D.Transform>
    			<Transform3DGroup>
    				<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
    				<ScaleTransform3D ScaleX="1" ScaleY="1" ScaleZ="1"/>
    				<RotateTransform3D d:EulerAngles="0,0,0">
    					<RotateTransform3D.Rotation>
    						<AxisAngleRotation3D Angle="0" Axis="0,1,0"/>
    					</RotateTransform3D.Rotation>
    				</RotateTransform3D>
    				<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
    				<TranslateTransform3D OffsetY="2.266" OffsetZ="0.319"/>
    			</Transform3DGroup>
    		</ModelVisual3D.Transform>
    		<ModelVisual3D x:Name="AmbientLightContainer">
    			<ModelVisual3D.Content>
    				<AmbientLight x:Name="AmbientLight" Color="#FF7F7F7F"/>
    			</ModelVisual3D.Content>
    		</ModelVisual3D>
    		<ModelVisual3D x:Name="DirectionalLightContainer">
    			<ModelVisual3D.Content>
    				<DirectionalLight x:Name="DirectionalLight" Color="#FF3F3F3F" Direction="0,0,-1">
    					<DirectionalLight.Transform>
    						<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="3"/>
    					</DirectionalLight.Transform>
    				</DirectionalLight>
    			</ModelVisual3D.Content>
    		</ModelVisual3D>
    		<ModelVisual3D x:Name="EntirePen">
    			<ModelVisual3D x:Name="Pen">
    				<ModelVisual3D x:Name="PenTip">
    					<ModelVisual3D.Transform>
    						<Transform3DGroup>
    							<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
    							<ScaleTransform3D ScaleX="1" ScaleY="1" ScaleZ="1"/>
    							<RotateTransform3D d:EulerAngles="0,0,0">
    								<RotateTransform3D.Rotation>
    									<AxisAngleRotation3D Angle="0" Axis="0,1,0"/>
    								</RotateTransform3D.Rotation>
    							</RotateTransform3D>
    							<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
    							<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
    						</Transform3DGroup>
    					</ModelVisual3D.Transform>
    					<ModelVisual3D x:Name="Tip_FeltContainer">
    						<ModelVisual3D.Content>
    							<GeometryModel3D x:Name="Tip_Felt" d:Bounds="-14.3089838027954,1.01379096508026,-0.0882589966058731,0.295544624328613,0.176519989967346,0.176519997417927">
    								<GeometryModel3D.Material>
    									<MaterialGroup>
    										<EmissiveMaterial Brush="Black"/>
    										<DiffuseMaterial Brush="Black"/>
    										<SpecularMaterial Brush="sc#1, 0.25, 0.25, 0.25" SpecularPower="17.647059"/>
    									</MaterialGroup>
    								</GeometryModel3D.Material>
    								<GeometryModel3D.Geometry>
    									<MeshGeometry3D Normals="0,0.707107,-0.70710657 0,0.707107,-0.70710657 0,0.96592642,-0.25881682 0,0.96592642,-0.25881682 0,0.96592642,0.25881681 0,0.96592642,0.25881681 0,0.70710702,0.70710655 0,0.70710702,0.70710655 0,0.25881722,0.96592632 0,0.25881722,0.96592632 0,-0.25881689,0.9659264 0,-0.25881689,0.9659264 0,-0.70710636,0.7071072
    0,-0.70710636,0.7071072 0,-0.96592716,0.25881408 0,-0.96592716,0.25881408 0,-0.96592642,-0.25881682 0,-0.96592642,-0.25881682 0,-0.70710087,-0.70711269 0,-0.70710087,-0.70711269 0,-0.25881689,-0.9659264 0,-0.25881689,-0.9659264 0,0.25881722,-0.96592632 0,0.25881722,-0.96592632 -0.23420937,0.68743936,-0.68743952 -0.23420771,0.93906062,-0.25161855
    -0.23420725,0.93906073,0.25161857 -0.23420867,0.6874395,0.68743962 -0.23420842,0.25161848,0.93906047 -0.23420787,-0.25161843,0.93906062 -0.23420923,-0.68743924,0.68743969 -0.23420746,-0.93906116,0.25161677 -0.23421154,-0.93905973,-0.25161831 -0.23421343,-0.68743492,-0.68744258 -0.23420841,-0.25161838,-0.93906049 -0.23420865,0.25161845,-0.93906042 0,0.707107,-0.70710657 0,0.96592642,-0.25881682 0,0.96592642,0.25881681
    0,0.70710702,0.70710655 0,0.25881722,0.96592632 0,-0.25881689,0.9659264 0,-0.70710636,0.7071072 0,-0.96592716,0.25881408 0,-0.96592642,-0.25881682 0,-0.70710087,-0.70711269 0,-0.25881689,-0.9659264 0,0.25881722,-0.96592632 -0.98171005,0.18389522,-0.049273936 -0.98171022,0.13461996,-0.13461984 -1,0,0 -0.9817101,0.18389452,0.049275618
    -0.98170991,0.1346176,0.13462447 -0.98171005,0.049274041,0.1838952 -0.98171009,-0.049273991,0.18389501 -0.98171024,-0.13461641,0.13462328 -0.98171039,-0.18389307,0.049275231 -0.9817101,-0.18389499,-0.049273872 -0.98171025,-0.13461986,-0.13461974 -0.98171005,-0.049274043,-0.1838952 -0.98171007,0.049274014,-0.1838951" Positions="-14.094623,1.166662,-0.064609997 -14.22631,1.166662,-0.064609997 -14.22631,1.190311,-0.023647999 -14.094623,1.190311,-0.023647999 -14.22631,1.190311,0.02365 -14.094623,1.190311,0.02365 -14.22631,1.166662,0.064612001 -14.094623,1.166662,0.064612001 -14.22631,1.1257,0.088261001 -14.094623,1.1257,0.088261001 -14.22631,1.078402,0.088261001 -14.094623,1.078402,0.088261001 -14.22631,1.0374399,0.064612001
    -14.094623,1.0374399,0.064612001 -14.22631,1.013791,0.02365 -14.094623,1.013791,0.02365 -14.22631,1.013791,-0.023649 -14.094623,1.013791,-0.023649 -14.22631,1.0374399,-0.064609997 -14.094623,1.0374399,-0.064609997 -14.22631,1.078402,-0.088258997 -14.094623,1.078402,-0.088258997 -14.22631,1.1257,-0.088258997 -14.094623,1.1257,-0.088258997 -14.268888,1.166662,-0.064609997 -14.268888,1.190311,-0.023647999
    -14.268888,1.190311,0.02365 -14.268888,1.166662,0.064612001 -14.268888,1.1257,0.088261001 -14.268888,1.078402,0.088261001 -14.268888,1.0374399,0.064612001 -14.268888,1.013791,0.02365 -14.268888,1.013791,-0.023649 -14.268888,1.0374399,-0.064609997 -14.268888,1.078402,-0.088258997 -14.268888,1.1257,-0.088258997 -14.013439,1.166662,-0.064609997 -14.013439,1.190311,-0.023647999 -14.013439,1.190311,0.02365
    -14.013439,1.166662,0.064612001 -14.013439,1.1257,0.088261001 -14.013439,1.078402,0.088261001 -14.013439,1.0374399,0.064612001 -14.013439,1.013791,0.02365 -14.013439,1.013791,-0.023649 -14.013439,1.0374399,-0.064609997 -14.013439,1.078402,-0.088258997 -14.013439,1.1257,-0.088258997 -14.308984,1.128366,-0.0070500001 -14.308984,1.121315,-0.019262999 -14.308984,1.102051,1E-06 -14.308984,1.128366,0.0070520001
    -14.308984,1.121315,0.019264 -14.308984,1.109102,0.026315 -14.308984,1.095,0.026315 -14.308984,1.082787,0.019264 -14.308984,1.075736,0.0070520001 -14.308984,1.075736,-0.0070500001 -14.308984,1.082787,-0.019262999 -14.308984,1.095,-0.026314 -14.308984,1.109102,-0.026314" TextureCoordinates="0.70045998,0.30637712 0.30295791,0.30465216 0.30295735,0.21179203 0.70046055,0.2148991 0.30295735,0.21179203 0.70046055,0.2148991 0.30295791,0.30465216 0.70045998,0.30637712 0.30295737,0.43239571 0.70046053,0.43292465 0.30295732,0.56760396 0.70046058,0.56707502 0.30295791,0.69534784 0.70045998,0.69362288 0.30295735,0.78820797 0.70046055,0.7851009 0.30295777,0.7882072 0.70046012,0.78510016 0.30295791,0.69534784 0.70045998,0.69362288 0.30295732,0.56760396 0.70046058,0.56707502 0.30295737,0.43239571
    0.70046053,0.43292465 0.22398695,0.34873939 0.22398636,0.2851084 0.22398635,0.2851084 0.22398695,0.34873939 0.22398638,0.4464432 0.22398632,0.55355653 0.22398695,0.65126061 0.22398635,0.7148916 0.2239868,0.71489129 0.22398695,0.65126061 0.22398632,0.55355653 0.22398638,0.4464432 0.82372097,0.37871262 0.82372151,0.33038536 0.82372151,0.33038536 0.82372097,0.37871262 0.82372149,0.45653769 0.82372154,0.5434621 0.82372097,0.62128738 0.82372151,0.66961464 0.8237211,0.66961449 0.82372097,0.62128738
    0.82372154,0.5434621 0.82372149,0.45653769 0.058031992,0.44396641 0.058032277,0.45907926 1.2850448E-07,0.49999987 0.058031989,0.44396641 0.058030798,0.45907923 0.058029934,0.48505785 0.05802987,0.5149419 0.058030622,0.54092052 0.058031749,0.55603334 0.058031752,0.55603334 0.058032101,0.54092049 0.05803189,0.51494188 0.058031954,0.48505787" TriangleIndices="0 1 2 0 2 3 3 2 4 3 4 5 5 4 6 5 6 7 7 6 8 7 8 9 9 8 10 9 10 11 11 10 12 11 12 13 13 12 14 13 14 15 15 14 16 15 16 17 17 16 18 17 18 19 19 18 20 19 20 21 21 20 22 21 22 23 23 22 1 23 1 0 1 24 25 1 25 2 2 25 26 2 26 4 4 26 27 4 27 6 6 27 28 6 28 8 8 28 29 8 29 10 10 29 30 10 30 12 12 30 31 12 31 14 14 31 32 14 32 16 16 32 33 16 33 18 18 33 34 18 34 20 20 34 35 20 35 22 22 35 24 22 24 1 36 0 3 36 3 37 37 3 5 37 5 38 38 5 7 38 7 39 39 7 9 39 9 40 40 9 11 40 11 41 41 11 13 41 13 42 42 13 15 42 15 43 43 15 17 43 17 44 44 17 19 44 19 45 45 19 21 45 21 46 46 21 23 46 23 47 47 23 0 47 0 36 48 49 50 51 48 50 52 51 50 53 52 50 54 53 50 55 54 50 56 55 50 57 56 50 58 57 50 59 58 50 60 59 50 49 60 50"/>
    								</GeometryModel3D.Geometry>
    							</GeometryModel3D>
    						</ModelVisual3D.Content>
    						<ModelVisual3D.Transform>
    							<Transform3DGroup>
    								<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
    								<ScaleTransform3D ScaleX="1" ScaleY="1" ScaleZ="1"/>
    								<RotateTransform3D d:EulerAngles="0,0,0">
    									<RotateTransform3D.Rotation>
    										<AxisAngleRotation3D Angle="0" Axis="0,1,0"/>
    									</RotateTransform3D.Rotation>
    								</RotateTransform3D>
    								<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
    								<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
    							</Transform3DGroup>
    						</ModelVisual3D.Transform>
    					</ModelVisual3D>
    				</ModelVisual3D>
    			</ModelVisual3D>
    		</ModelVisual3D>
    	</ModelVisual3D>
    </Viewport3D>
    
    


  • 20. října 2009 18:06Rob RelyeaModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    The Window (or other class) with a namescope, needs to be the root element that you load...not the root element of the page that has your button.

    Perhaps you could make Viewport3DWithNameScope, make that the root of the 3d xaml file, and then all should be happy.
    Thanks, Rob
  • 20. října 2009 19:43EeeeEfff Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Obsahuje kód
    Got it - sorry for the confusion, I didn't quite get that the XAML file that's loaded needed to have the NameScope implementer as its root.  Thanks very much.   Awesome help, as usual.

    E.

    -------------

    some time later...  thought I'd share my final solution (thanks to Rob's suggestions):
    1. I created a Grid which implemented INameScope
        public class NameScopedGrid : Grid, INameScope {
    
            Dictionary<string, object> nameTable = new Dictionary<string, object>();
    
            object INameScope.FindName(string name) {
                object element = null;
                nameTable.TryGetValue(name, out element);
                return element;
            }
    
            void INameScope.RegisterName(string name, object scopedElement) {
                nameTable[name] = scopedElement;
            }
    
            void INameScope.UnregisterName(string name) {
                nameTable[name] = null;
            }
    
        }
    
    

    2. created 2 strings, one to prepend to my xaml stream and to append to it:
            string prepend = "<local:NameScopedGrid xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:local=\"clr-namespace:LoadXAML3D;assembly=LoadXAML3D\">";
            string append = "</local:NameScopedGrid>";
    
    

    3. created a memory stream, prepended the 1st string above, appended the contents of the xaml file (read into a byte[]), and appended the 2nd string above.
                int count = 0;
                byte[] byteData = null;
    
                // create a memory stream
                MemoryStream memStream = new MemoryStream(1024);
    
                // Write the first string to the stream.
                byteData = Encoding.ASCII.GetBytes(prepend);
                memStream.Write(byteData, 0, byteData.Length);
    
                memStream.Seek(0, SeekOrigin.End);
                // read the XAML file contents
                byte[] fileData = readFile(fileName);
                // Write the file contents to the stream, byte by byte.
                count = 0;
                while (count < fileData.Length) {
                    memStream.WriteByte(fileData[count++]);
                }
    
                memStream.Seek(0, SeekOrigin.End);
                // Write the second string to the stream.
                byteData = Encoding.ASCII.GetBytes(append);
                memStream.Write(byteData, 0, byteData.Length);
                memStream.Seek(0, SeekOrigin.Begin);
    
    

    4. read the stream, and place the resulting NameScopedGrid into the UI.
                // read the stream using XamlReader, and cast the result to NameScopedGrid.
                // this ends up populating NameScopedGrid.nameTable with the named elements in the XAML file
                NameScopedGrid grid = (NameScopedGrid)System.Windows.Markup.XamlReader.Load(memStream);
                
                // don't forget to close the memory stream
                memStream.Close();
    
                // add the NameScopedGrid to the UI - in this case, to my Border object
                host.Child = grid;
    
    

    Awesome.



    • UpravenýEeeeEfff 21. října 2009 7:01to share my solution
    •