2016-10-11 11 views
3

Я пытаюсь создать расширение разметки, которое упрощает запись URI для свойства Source WPF ResourceDictionary.MarkupExtension в ResourceDictionary.Source свойство

Минимальный пример проблемы заключается в следующем:

CS:

public class LocalResourceExtension : MarkupExtension 
{ 
    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return new Uri("Resources.xaml", UriKind.Relative); 
    } 
} 

XAML:

<UserControl ...> 
    <UserControl.Resources> 
     <ResourceDictionary Source="{mw:LocalResource}" /> <!-- error MC3022 --> 
     <!-- <ResourceDictionary Source="Resources.xaml" /> --> <!-- Works fine --> 
    </UserControl.Resources> 
<!-- ... --> 
</UserControl> 

Это не компилировать с следующей ошибкой:

error MC3022: All objects added to an IDictionary must have a Key attribute or some other type of key associated with them. 

Однако, если я заменю расширение разметки постоянным значением (как показано в комментариях), все работает нормально.

Почему версия с расширением разметки не работает? Есть ли обходной путь?

Я использую MSVC 2015

+1

Вы пытались поместить его в ''? –

+0

@EdPlunkett Отличное обходное решение, спасибо. Не думал об этом. Тем не менее, в этом случае мое расширение не «упрощает», потому что оно добавляет еще 4 строки для каждого использования ... – nevermind

+0

Он также не работает во время разработки, поэтому он синим-squiggles элемент ResourceDictionary. Безвредный, но раздражающий. Реальное решение здесь, я думаю, состоит в том, чтобы просто написать обычный словарь ресурсов, который объединяет все, что вам нужно, и включать это явно. –

ответ

2

Это работает для меня:

public class LocalResource : MarkupExtension 
{ 
    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return new ResourceDictionary() { 
      Source = new Uri("Resources.xaml", UriKind.Relative) 
     }; 
    } 
} 

XAML

<Window.Resources> 
    <myNamespace:LocalResource /> 
</Window.Resources> 

Часть XAML редактор голубые загогулины <myNamespace:LocalResource /> во время разработки, которая убивает Дизайн. Таким образом, это работает, только если вы не используете представление «Дизайн». Я этого не делаю, но некоторые делают.

Я продолжаю рассказывать своей девушке. Я величайший гений с Галилея, и она мне просто не верит. Galileo нашел бы способ сделать работу над дизайном.

UPDATE

Решение номер два:

public class LocalResourceDictionary : ResourceDictionary 
{ 
    public LocalResourceDictionary() 
    { 
     Source = new Uri("Resources.xaml", UriKind.Relative); 
    } 
} 

XAML

<Window.Resources> 
    <myNamespace:LocalResourceDictionary /> 
</Window.Resources> 

Это правильно работает во время выполнения, заглушает загогулина, и позволяет разработчикам работать. Тем не менее, он молча не может объединить файл ресурсов в режиме разработки. Все еще не идеально.

ОБНОВЛЕНИЕ

ОП умнее меня. Это делает все:

public class LocalResourceDictionary : ResourceDictionary 
{ 
    public LocalResourceDictionary() 
    { 
     Source = new Uri("pack://application:,,,/MyAssemblyName;component/Resourc‌​es.xaml", UriKind.Absolute); 
    } 
} 
+0

Прохладный! Второе решение даже работает в режиме проектирования, если LocalResourceDictionary предоставляет абсолютный URI (начиная с pack: //). – nevermind

+0

@nevermind Awesome. Я пробовал играть в пачку, но я не мог заставить его работать. Какую именно строку вы использовали? –

+1

'Source = new Uri (" pack: // application: ,,,/MyAssemblyName; component/Resources.xaml ", UriKind.Absolute);' работает для меня. – nevermind