#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 являются словарями ресурсов, и тесловари ресурсов, контролируют расположение, стиль, цвет и т. Д. Для кнопок