Set relative path of baml/xaml in *.g.cs using MarkupCompilePass1

150 Views Asked by At

Currently I'm compiling xaml to baml using MarkupCompilePass1. This is working pretty well, besides of the relative paths which points to the baml/xaml ressources. For example let's assume the xaml file is in the directory ui/controls/test.xaml, than the generated code (test.g.cs) should look like this:

_contentLoaded = true;
System.Uri resourceLocater = new System.Uri("/Sample01;component/ui/controls/test.xaml", System.UriKind.Relative);

#line 1 "test.xaml"
System.Windows.Application.LoadComponent(this, resourceLocater);

But it currently looks like this:

_contentLoaded = true;
System.Uri resourceLocater = new System.Uri("/Sample01;component/test.xaml", System.UriKind.Relative); // <--- Here is the problem

#line 1 "test.xaml"
System.Windows.Application.LoadComponent(this, resourceLocater);

How can I solve this issue? The Uri is not complete, becuase it does not contain /ui/controls.

EDIT 1

Here is the current code which generates the baml and *.g.cs

foreach (var _xaml in xamlSources)
{
    // Relative path to the xaml file
    _xaml.RelativePath = _xaml.RelativePath = Path.GetDirectoryName(_xaml.Path.Replace(CXUIBuildEngine.ProjectRoot, ""));

    _task = new MarkupCompilePass1();
    _task.BuildEngine = BuildEngine;
    _task.RequirePass2ForMainAssembly = false;
    _task.OutputType = "library";

    // List of xaml to compile, im this case just one,
    // because only one output is allowed so we have to set
    // the specific output per compile process...
    _task.PageMarkup = new[] { new XamlItem(_xaml.Path) };

    // Set default namespace
    if (!string.IsNullOrWhiteSpace(CXUIBuildEngine.RootNamespace))
    {
        _task.RootNamespace = CXUIBuildEngine.RootNamespace;
    }

    // Set default options
    _task.AssemblyName = CXUIBuildEngine.AssemblyName;
    _task.Language = "cs";

    // !!! Here we combine the output path with the relative path,
    // !!! This is maybe already the fault
    _task.OutputPath = Path.Combine(TempOutputDirectory, _xaml.RelativePath);

    // Add all references as XamlItem
    if (CXUIBuildEngine.References != null)
    {
        _task.References = CXUIBuildEngine.References.Select(item => new XamlItem(item.Location)).ToArray();
    }

    if (!_task.Execute())
    {
        return false;
    }
}

Thank you a lot!

1

There are 1 best solutions below

0
On

Setting the Link and LogicalName in the XamlPages / Items seems to help:

var _item = new XamlItem(_xaml.Path);
_item.SetMetadata("Link", _xaml.RelativePath + "\\" + Path.GetFileName(_xaml.Path));
_item.SetMetadata("LogicalName", _xaml.RelativePath + "\\" + Path.GetFileName(_xaml.Path));
_task.PageMarkup = new[] { _item };

This properties are only saved in a Dictioary<string, string> inside of the item.