Как назначить результат привязки для ResourceKey DynamicResource? - PullRequest
0 голосов
/ 17 января 2020

Я хотел бы динамически переключать изображение в соответствии со значением свойства. Путь к изображению определяется в двух ResourceDictory для одного и того же ключа.

Для этого я написал код XAML, как показано ниже.

<HierarchicalDataTemplate DataType="{x:Type solutionPackage:ProjectStruct}" ItemsSource="{Binding Children}">
    <StackPanel Orientation="Horizontal">
        <Image Width="16" Height="16" Margin="0 0 5 0" 
               Source="{Binding Extension, Converter={localConverters:ToResourceKeyConverter}, ConverterParameter='Extension'}"/>
        <TextBlock Text="{Binding NameWithoutExtension}"/>
    </StackPanel>
</HierarchicalDataTemplate>

Ниже приведен код преобразователя.

class ToResourceKeyConverter : MarkupExtension, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null) return null;
        if (parameter == null) return null;

        if (parameter.ToString() == "Extension")
        {
            if (value.ToString() == ".mcproj")
                return Application.Current.Resources["MCProjectImagePath"];
        }

        return null;
    }

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

    public override object ProvideValue(IServiceProvider serviceProvider) => this;
}

На следующем рисунке показано, что делает вышеуказанный код.

enter image description here

MCProjectImagePath определен в двух ResourceDictory. один - DarkThemeImageResources.xaml, а другой - BasicImageResources.xaml.

Каждый код выглядит так, как показано ниже.

В BasicImageResource.xaml

<BitmapImage x:Key="ProjectImagePath" UriSource="/Resources/Images/Basic/project.png"/>
<BitmapImage x:Key="MCProjectImagePath" UriSource="/Resources/Images/Basic/mcproject.png"/>

В DarkThemeImageResources.xaml

<BitmapImage x:Key="ProjectImagePath" UriSource="/Resources/Images/DarkTheme/project.png"/>
<BitmapImage x:Key="MCProjectImagePath" UriSource="/Resources/Images/DarkTheme/mcproject.png"/>

Обратите внимание, что он имеет тот же ключ, но значение UriSource отличается.

На данный момент функция работает хорошо, но не переключает изображение, когда пользователь нажимает какую-либо кнопку. Поэтому я подумал, что должен использовать ключевое слово DynamicResource для динамического переключения, поэтому я изменил код XAML, как показано ниже.

<HierarchicalDataTemplate DataType="{x:Type solutionPackage:ProjectStruct}" ItemsSource="{Binding Children}">
    <StackPanel Orientation="Horizontal">
        <Image Width="16" Height="16" Margin="0 0 5 0" 
               Source="{DynamicResource ResourceKey={Binding Extension, Converter={localConverters:ToResourceKeyConverter}, ConverterParameter='Extension'}}"/>
        <TextBlock Text="{Binding NameWithoutExtension}"/>
    </StackPanel>
</HierarchicalDataTemplate>

Моя идея заключается в том, что результатом привязки является ResourceKey, поэтому назначьте результат привязки ResourceKey в DynamicResource .

Компиляция работает хорошо, но не входит в приведенный выше код ToResourceKeyConverter, поэтому изображение не отображается.

Я хотел бы динамически переключать ресурсы (например, изображение), когда нажата специальная кнопка щелкнул. действие нажатия специальной кнопки не влияет на значение свойства Extension. Он просто заменяет ThemeDictory, как показано ниже.

private void OnOption()
{
    // for test
    var app = (App)Application.Current;

    List<Uri> uris = new List<Uri>
    {
        new Uri("Resources/BasicImageResources.xaml", UriKind.RelativeOrAbsolute)
    };

    app.ChangeTheme(uris);
}

public void ChangeTheme(List<Uri> uris)
{
    foreach (var uri in uris)
        ThemeDictionary.MergedDictionaries.Add(new ResourceDictionary() { Source = uri });

    var dictionary = ThemeDictionary.MergedDictionaries.ToList();

    foreach(var item in dictionary)
    {
        if (uris.Contains(item.Source)) continue;
        ThemeDictionary.MergedDictionaries.Remove(item);
    }
}

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

Спасибо за чтение.

1 Ответ

0 голосов
/ 17 января 2020

Вам необходимо реализовать интерфейс INotifyPropertyChanged для обработки уведомлений об изменениях. например,

class ProjectStruct : INotifyPropertyChanged
{
    //......
    //Your code
    //......

    private string extension;

    public string Extension
    {
        get { return extension; }
        set
        {
            extension = value;
            // Call OnPropertyChanged whenever the property is updated
            OnPropertyChanged("Extension");
        }
    }

    .....
    Interface implementation
    .....
}

In xaml

<HierarchicalDataTemplate DataType="{x:Type solutionPackage:ProjectStruct}" ItemsSource="{Binding Children}">
<StackPanel Orientation = "Horizontal" >
<Image Width= "16" Height= "16" Margin= "0 0 5 0"
   Source= "{Binding Extension Converter={localConverters:ToResourceKeyConverter} ConverterParameter='Extension' Mode=OneWay}"/>
<TextBlock Text= "{Binding NameWithoutExtension}" />
</StackPanel >
</HierarchicalDataTemplate >
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...