Question

I have a XAML file of some view where a complex 3D model is defined. The problem is that the part defining the model is quite big, it has over 0.5 MB and it's really hard to browse through the file. Is there a way I can move e.g the Model3DGroup into another file and then include it in my main XAML file? I use a SketchUp to XAML converter which creates files with <Model3DGroup xmlns="..." xmlns:x="..."> as their roots, so I'm almost sure it can be done in a convenient way.

My current XAML file looks like this:

<UserControl x:Class="BigAtom.Views.WorkspaceView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:TestProj"
             mc:Ignorable="d" 
             d:DesignHeight="278" d:DesignWidth="274">

    <Grid x:Name="RootVisual" Background="Beige" ClipToBounds="True">
        <Canvas Name="DrawingCanvas" Grid.Row="0" Grid.Column="0" Width="0" Height="0" RenderTransform="1,0,0,-1,0,0" Margin="10">
            <Viewport3D Name="Object3D" Width="50" Height="50" Margin="-25,-25" ClipToBounds="False">
                <Viewport3D.Camera>
                    <OrthographicCamera x:Name="CamMain" Position="0 60 100" LookDirection="0 -60 -100"></OrthographicCamera>
                </Viewport3D.Camera>
                <ModelVisual3D>
                    <ModelVisual3D.Content>
                        <DirectionalLight x:Name="DirLightMain" Direction="-1,-1,-1"/>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
                <ModelVisual3D x:Name="MyModel">
                    <ModelVisual3D.Content>
                        <Model3DGroup>
                            <GeometryModel3D>
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D Positions="-5.6166 10.4050 153.1136 [very long line]" TextureCoordinates="-5.616612 -10.405044  -3.582495 [very long line]" TriangleIndices="164 17 57 [very long line]"/>
                                </GeometryModel3D.Geometry>
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Color="White" Brush="#ffffff"/>
                                </GeometryModel3D.Material>
                                <GeometryModel3D.BackMaterial>
                                    <DiffuseMaterial Color="White" Brush="White"/>
                                </GeometryModel3D.BackMaterial>
                            </GeometryModel3D>
                        </Model3DGroup>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
            </Viewport3D>
        </Canvas>
    </Grid>
</UserControl>

and I want to achieve something like this:

<UserControl x:Class="BigAtom.Views.WorkspaceView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:TestProj"
             mc:Ignorable="d" 
             d:DesignHeight="278" d:DesignWidth="274">

    <Grid x:Name="RootVisual" Background="Beige" ClipToBounds="True">
        <Canvas Name="DrawingCanvas" Grid.Row="0" Grid.Column="0" Width="0" Height="0" RenderTransform="1,0,0,-1,0,0" Margin="10">
            <Viewport3D Name="Object3D" Width="50" Height="50" Margin="-25,-25" ClipToBounds="False">
                <Viewport3D.Camera>
                    <OrthographicCamera x:Name="CamMain" Position="0 60 100" LookDirection="0 -60 -100"></OrthographicCamera>
                </Viewport3D.Camera>
                <ModelVisual3D>
                    <ModelVisual3D.Content>
                        <DirectionalLight x:Name="DirLightMain" Direction="-1,-1,-1"/>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
                <ModelVisual3D x:Name="MyModel">
                    <ModelVisual3D.Content>
                        <Model3DGroup --- some kind of reference to the file which keeps the 3D model --- />
                    </ModelVisual3D.Content>
                </ModelVisual3D>
            </Viewport3D>
        </Canvas>
    </Grid>
</UserControl>

@edit

McGarnagle's answer is generally OK, but in my case I also have some DataTemplate defined in my UserControl.Resources. Because of this, I had to create such a structure:

<UserControl.Resources>
    <ResourceDictionary>
        <DataTemplate DataType="{x:Type local:SomeType}" x:Key="SomeTypeTemplate">
            ....
        </DataTemplate>
        <ResourceDictionary.MergedDictionaries>
           <ResourceDictionary Source="Models.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>
Was it helpful?

Solution

I imagine you should be able to use a resource dictionary for this. Add a file, say, "Models.xaml" with the definitions:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Model3DGroup x:Key="TheModelContent">
        ...
    </Model3DGroup>
</ResourceDictionary> 

Then reference the file in your UserControl, and refer to the models using the StaticResource keyword:

<UserControl>
    <UserControl.Resources> 
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Models.xaml" />
            </ResourceDictionary.MergedDictionaries>

            <!-- other resources here -->
        </ResourceDictionary>
    </UserControl.Resources>
    ...

    <ModelVisual3D Content="{StaticResource TheModelContent}">
    ...

</UserControl>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top