WPF Как присвоить нескольким словарям ресурсов один и тот же класс?

#c# #wpf #visual-studio #xaml #resourcedictionary

#c# #wpf #visual-studio #xaml #resourcedictionary

Вопрос:

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

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

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

Проблема сейчас в том, что когда я присваиваю нескольким словарям ресурсов один и тот же класс, я получаю эту ошибку. В app.xaml уже были загружены некоторые стили, но даже после загрузки только одного набора стилей я все равно получил ту же ошибку.

Это тоже странно, потому что раньше казалось, что он работает, но при простом перезапуске Visual Studio проблема возникла.

В этом изображении есть 2 словаря ресурсов для каждого стиля, но только одному из них присвоен класс.

Итак, как мне назначить этот класс EventHandler нескольким словарям ресурсов? Или есть лучший способ сделать это?

Ответ №1:

Я привел для вас небольшой пример. Я добавил в проект два словаря ресурсов с именами Dark.xaml и Light.xaml.

введите описание изображения здесь

Я определил цвета, которые я буду использовать в этих словарях ресурсов.

Темный код.xaml

 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:ThemeExample">
<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary>
        <SolidColorBrush x:Key="ColorMode" Color="DarkBlue"/>
    </ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
 

Код Light.xaml

 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:ThemeExample">

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary>
        <SolidColorBrush x:Key="ColorMode" Color="LightBlue"/>
    </ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
 

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

Код MainWindow.xaml

 <Button x:Name="DarkButton" Content="Dark" HorizontalAlignment="Left" Margin="151,132,0,0" VerticalAlignment="Top" Width="75" Click="DarkButton_Click"/>
    <Button x:Name="LightButton" Content="Light" HorizontalAlignment="Left" Margin="248,132,0,0" VerticalAlignment="Top" Width="75" Click="LightButton_Click"/>
    <Rectangle Fill="{DynamicResource ColorMode}" Width="100" Height="100"></Rectangle>
 

Код LightButton_Click

  private void LightButton_Click(object sender, RoutedEventArgs e)
    {
        var resources = Application.Current.Resources.MergedDictionaries;

        var existingResourceDictionary = Application.Current.Resources.MergedDictionaries
                                        .Where(rd => rd.Source != null)
                                        .SingleOrDefault(rd => Regex.Match(rd.Source.OriginalString, @"(/((Light)|(Dark)))").Success);

        var source = $"pack://application:,,,/Light.xaml";
        var newResourceDictionary = new ResourceDictionary() { Source = new Uri(source) };

        Application.Current.Resources.MergedDictionaries.Remove(existingResourceDictionary);
        Application.Current.Resources.MergedDictionaries.Add(newResourceDictionary);
    }
 

DarkButton_Click

 private void DarkButton_Click(object sender, RoutedEventArgs e)
    {
        var resources = Application.Current.Resources.MergedDictionaries;

        var existingResourceDictionary = Application.Current.Resources.MergedDictionaries
                                        .Where(rd => rd.Source != null)
                                        .SingleOrDefault(rd => Regex.Match(rd.Source.OriginalString, @"(/((Light)|(Dark)))").Success);

        var source = $"pack://application:,,,/Dark.xaml";
        var newResourceDictionary = new ResourceDictionary() { Source = new Uri(source) };

        Application.Current.Resources.MergedDictionaries.Remove(existingResourceDictionary);
        Application.Current.Resources.MergedDictionaries.Add(newResourceDictionary);
    }
 

Не забудьте включить один и тот же цветовой ключ в app.xaml.

 <Application x:Class="ThemeExample.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:ThemeExample"
         StartupUri="MainWindow.xaml">
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary>
                <SolidColorBrush x:Key="ColorMode" Color="DarkBlue"/>
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>
 

Комментарии:

1. Это замечательно, но у меня есть стиль, в котором есть текстовое поле, в котором мне нужно получить событие изменения текстового поля. и поскольку это ресурс, ему нужен класс, чтобы направлять событие

2. это стиль для сетки, и в этой сетке есть такое текстовое поле

3. Я не смог установить связь между цветовой темой и текстовым полем. Вы уверены, что то, что вы делаете, правильно? Кроме того, я не совсем понимаю, что вы хотите сделать. Извините, мой английский не очень хорош.

4. У меня есть сетка 1, эта сетка содержит стиль, и в этом стиле в ContentPresenter есть текстовый блок, мне нужно управлять событиями для этого текстового блока, чтобы сделать это, мне нужно присвоить ему класс, так как файлы xaml являются словарями ресурсов, и тесловари ресурсов, контролируют расположение, стиль, цвет и т. Д. Для кнопок