XAML MarkupExtension, которое знает путь к файлу xaml, создающему его экземпляр

В переопределении MarkupExtension.ProvideValue() при выполнении в режиме разработки, как мне получить путь к файлу xaml, который создал это расширение разметки? То есть я могу знать, что файл xaml создает экземпляр моего расширения разметки из моего расширения разметки в режиме разработки?

Я создаю расширенную версию d:DesignData. Итак, данный файл MyControl.xaml:

<UserControl x:Class="MyControl"
         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:mns="clr-namespace:MyNameSpace"
         mc:Ignorable="d" 
         d:DataContext="{d:DesignData Source=../../../SampleData/SampleDataContext.xaml}"/>

При открытии в Visual Studio xaml конструкторе MyControl.DataContext будет назначено содержимое файла SampleDataContext.xaml, расположенного в файловой системе относительно MyControl.xaml.

Я могу настроить основы расширения, достаточно просто:

namespace MyNameSpace
{
    public class MyDesignDataExtension : MarkupExtension
    {
        public string Source { get; set; }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            var s = new FileStream(Source, FileMode.Open);
            var xamlRoot = XamlReader.Load(s);
            s.Close();
            return xamlRoot;
        }
    }
}

Однако FileStream использует мой путь установки Visual Studio в качестве базового пути. Таким образом, когда я использую мое расширение данных дизайна

d:DataContext="{mns:MyDesignData Source=../../../SampleData/SampleDataContext.xaml}"

Я получаю исключение. "Не удалось найти файл 'C:/Program Files (x86)/SampleData/SampleDataContext.xaml'. Поэтому мне нужно использовать путь к MyControl.xaml, чтобы либо обновить используемую базу каталогов, либо сгенерировать полный путь из моего относительного пути.

0 ответов

Вы можете использовать IUriContext услуги, предоставляемые IServiceProvider который вы получаете в качестве первого параметра ProvideValue метод:

public override object ProvideValue(IServiceProvider serviceProvider)
{
    Uri callerUri = ((IUriContext)serviceProvider.GetService(typeof(IUriContext))).BaseUri;
}
Другие вопросы по тегам