Я новичок в WPF, и совсем недавно в свободное время, работая над хобби-проектом, я столкнулся с очень похожей проблемой с аналогичными ограничениями.
Тем не менее, как вы уже поняли, application
отлично работает во время разработки, но не во время выполнения, а siteoforigin
— наоборот. Таким образом, один из логических способов решить эту проблему — просто использовать оба варианта: siteoforigin
во время выполнения и application
во время разработки.
Для этого вам нужно будет просто перехватить настройку свойства Source
вашего элемента управления. Один из способов сделать это — использовать наследование.
Ниже приведен пример, который делает это для ResourceDictionary:
Реализация
/// <summary>
/// A modified type of <see cref="ResourceDictionary"/> that translates "Resource" pack URIs to "Site of Origin"
/// pack URIs when in runtime.
///
/// i.e. This allows you to declare pack URIs as "pack://application:,,,", which will be resolved
/// as such in design mode while at runtime, actually using "pack://siteoforigin:,,,".
/// </summary>
public class SiteOfOriginResourceDictionary : ResourceDictionary
{
private const string SiteOfOriginPrefix = "pack://siteoforigin:,,,";
private const string ApplicationPrefix = "pack://application:,,,";
private const string UseRedirectSource = "Please use RedirectSource instead of Source";
private string _originalUri;
/// <summary>
/// Gets or sets the design time source.
/// </summary>
public string RedirectSource
{
get => _originalUri;
set
{
this._originalUri = value;
bool isInDesignMode = (bool) DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue;
if (! isInDesignMode)
{
if (value.Contains(ApplicationPrefix))
value = value.Replace(ApplicationPrefix, SiteOfOriginPrefix);
}
base.Source = new Uri(value);
}
}
/// <summary>
/// Please use <see cref="RedirectSource"/> instead.
/// </summary>
public new Uri Source
{
get => throw new Exception(UseRedirectSource);
set => throw new Exception(UseRedirectSource);
}
}
Пример использования
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<SiteOfOriginResourceDictionary RedirectSource="pack://application:,,,/Theme/Default/Root.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
На практике это решение сработало для меня, и я активно использую этот код. Я совершенно уверен, что вы можете сделать то же самое с Image
и/или другими компонентами WPF.
Тем не менее, в моем случае мне нужно было поддерживать это только на ResourceDictionary
. Это решение было бы неоптимальным в вашем случае, поскольку вам, вероятно, (в конечном итоге) потребуется сделать это для нескольких элементов управления в будущем.
Таким образом, я бы предложил в качестве потенциального решения дальнейшее исследование использования Attached Properties
, создание присоединенного свойства, которое устанавливает Source
элемента управления, переключение между application
во время разработки и siteoforigin
во время выполнения.
Вместо этого это можно было бы повторно использовать для нескольких элементов управления без необходимости наследовать каждый раз для каждого нового элемента управления/класса.
В связи с этим я не могу сказать, что знаю, почему использование application
работает в конструкторе, когда действие сборки для ресурса установлено на Content
. Согласно документации этот URI должен использоваться, когда ресурс "компилируется в сборку, на которую ссылаются" (Source), но, тем не менее, это работает для меня.
Это мой первый пост на StackOverflow, и я любитель, поэтому, пожалуйста, будьте со мной полегче ????.
person
Sewer56
schedule
18.05.2019