2009-03-29 3 views
8

У меня есть значения List с ResourceKey и Caption, эти значения являются строками. Ресурс - это имя фактического ресурса, определенного в словаре ресурсов. Каждая из этих значков ResourceKey - Canvas.Связывание свойства строки datacontext с ключом StaticResource

<Data ResourceKey="IconCalendar" Caption="Calendar"/> 
<Data ResourceKey="IconEmail" Caption="Email"/> 

У меня есть список, у которого есть набор данных с кнопкой и надпись под кнопкой. То, что я хочу сделать, это отобразить ресурс статического ресурса в качестве содержимого кнопки.

<ListView.ItemTemplate> 
    <DataTemplate> 
     <Grid> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="*" /> 
       <RowDefinition Height="Auto" /> 
      </Grid.RowDefinitions> 

      <Button Content="{Binding ResourceKey}" Template="{StaticResource RoundButtonControlTemplate}"/> 
      <TextBlock Grid.Row="1" Margin="0,10,0,0" Text="{Binding Caption}" HorizontalAlignment="Center" FontSize="20" FontWeight="Bold" /> 
     </Grid> 
    </DataTemplate> 
</ListView.ItemTemplate> 

Я думаю, что я попробовал все перестановки со связыванием StaticResource и т.д.

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

Благодаря

ответ

10

После того, как немного подумать, я в конечном итоге с помощью ValueConvertor так:

class StaticResourceConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var resourceKey = (string)value; 

     return Application.Current.Resources[resourceKey]; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new Exception("The method or operation is not implemented."); 
    } 
} 

и связывание на кнопке становится

<Button Content="{Binding ResourceKey, Converter={StaticResource resourceConverter}}" /> 
+1

Использование FindResource вместо индекса доступа []: return Application.Current.FindResource (value); он будет искать во всех ресурсах, а не только в app.xaml – Liero

+0

Не знаю почему, но мне пришлось использовать _App_.Current.Resources в отличие от Application.Current.Resources – Danielson

2

Здесь у меня есть улучшенная версия ответа @dvkwong (наряду с редактированием @Anatoliy Nikolaev):

class StaticResourceConverter : MarkupExtension, IValueConverter 
{ 
    private Control _target; 


    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var resourceKey = (string)value; 

     return _target?.FindResource(resourceKey) ?? Application.Current.FindResource(resourceKey); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     var rootObjectProvider = serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider; 
     if (rootObjectProvider == null) 
      return this; 

     _target = rootObjectProvider.RootObject as Control; 
     return this; 
    } 
} 

использование:

<Button Content="{Binding ResourceKey, Converter={design:StaticResourceConverter}}" /> 

Основное изменение состоит в следующем:

  1. Преобразователь теперь System.Windows.Markup.MarkupExtension поэтому он может быть использован непосредственно без декларируемых в качестве ресурса.

  2. Конвертер является контекстно-зависимым, поэтому он будет не только искать ресурсы вашего приложения, но и локальные ресурсы (текущее окно, пользовательский контроль или страница и т. Д.).

+0

TIL о MarkupExtension, это был хороший день , – amnesia

 Смежные вопросы

  • Нет связанных вопросов^_^