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;
}