Как назначить ресурсы WPF другим тегам ресурсов
Это довольно неясно, я могу просто упустить что-то очень простое.
Сценарий 1
Допустим, я создаю кисть градиента, как это в моем <Window.Resources>
раздел:
<LinearGradientBrush x:Key="GridRowSelectedBackBrushGradient" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#404040" Offset="0.0" />
<GradientStop Color="#404040" Offset="0.5" />
<GradientStop Color="#000000" Offset="0.6" />
<GradientStop Color="#000000" Offset="1.0" />
</LinearGradientBrush>
Тогда гораздо позже я хочу переопределить HighlightBrushKey
для DataGrid. Я в основном сделал это так (ужасно);
<LinearGradientBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
GradientStops="{Binding Source={StaticResource GridRowSelectedBackBrushGradient}, Path=GradientStops}"
StartPoint="{Binding Source={StaticResource GridRowSelectedBackBrushGradient}, Path=StartPoint}"
EndPoint="{Binding Source={StaticResource GridRowSelectedBackBrushGradient}, Path=EndPoint}" />
Это, очевидно, не самый приятный способ ссылки на ресурс. Я также придумал следующую проблему, которая почти идентична.
Сценарий 2
Скажем, я создал два цвета в моем <Window.Resources>
разметка, вот так:
<SolidColorBrush x:Key="DataGridRowBackgroundBrush" Color="#EAF2FB" />
<SolidColorBrush x:Key="DataGridRowBackgroundAltBrush" Color="#FFFFFF" />
Затем я хочу предоставить их в массиве, который передает ConverterParameter в привязку, чтобы я мог предоставить пользовательскому конвертеру мои экземпляры статического ресурса:
<Setter Property="Background">
<Setter.Value>
<Binding RelativeSource="{RelativeSource Mode=Self}"
Converter="{StaticResource BackgroundBrushConverter}">
<Binding.ConverterParameter>
<x:Array Type="{x:Type Brush}">
<SolidColorBrush Color="{Binding Source={StaticResource DataGridRowBackgroundBrush}, Path=Color}" />
<SolidColorBrush Color="{Binding Source={StaticResource DataGridRowBackgroundAltBrush}, Path=Color}" />
</x:Array>
</Binding.ConverterParameter>
</Binding>
</Setter.Value>
</Setter>
Я попытался сделать ссылку на существующий ресурс, но в своих усилиях я фактически воссоздал ресурс и связал свойства так, чтобы они соответствовали. Опять же, это не идеально.
Потому что я решил эту проблему хотя бы дважды, есть ли лучший способ?
Спасибо том
2 ответа
Мне было интересно, когда кто-то собирался спросить об этом.
Что вы хотите сделать в Сценарии 1, так это эффективно присвоить отдельному ресурсу "псевдоним". Это легко сделать с помощью разметки, которая кажется очевидной только после того, как вы ее увидите. Предположим, у нас есть это в нашем App.xaml или где-то:
<ResourceDictionary>
<LinearGradientBrush x:Key="GridRowSelectedBackBrushGradient" ... />
</ResourceDictionary>
Чтобы включить псевдоним в другой ResourceDictionary, просто:
<ResourceDictionary>
<StaticResourceExtension x:Key="{x:Static SystemColors.HighlightBrushKey}"
ResourceKey="GridRowSelectedBackBrushGradient" />
</ResourceDictionary>
Это ищет объект кисти в первом ResourceDictionary и добавляет тот же объект ко второму ResourceDictionary под новым ключом. Это также работает в пределах одного ResourceDictionary.
Для вашего сценария 2 решение так же просто:
<Binding.ConverterParameter>
<x:Array Type="{x:Type Brush}">
<StaticResourceExtension ResourceKey="DataGridRowBackgroundBrush" />
<StaticResourceExtension ResourceKey="DataGridRowBackgroundAltBrush" />
</x:Array>
</Binding.ConverterParameter>
Опять же, фактический Brush
объекты, найденные с помощью ResourceKey
добавляются непосредственно в Brush[]
массив. Ничего нового Brush
создано.
Я думаю, что мы все так привыкли использовать StaticResourceExtension
с синтаксисом расширения разметки (например, {StaticResource Xyz}
) что легко забыть, что он также может использоваться с обычным синтаксисом элемента.
Разметка, с которой вы работаете, недостаточно высока. Вы не создаете LinearGradientBrush
Ваш первый пример: вы просто ссылаетесь на ресурс. Например:
<DataGrid HighlightBrushKey="{StaticResource GridRowSelectedBackBrushGradient}" ....
Во втором примере я бы сказал, что вы хотите объявить массив как ресурс:
<x:Array Type="{x:Type Brush}" x:Key="MyArray">
<SolidColorBrush Color="#EAF2FB" />
<SolidColorBrush Color="#FFFFFF" />
</x:Array>
И тогда вы можете использовать
<Binding RelativeSource="{RelativeSource Mode=Self}"
Converter="{StaticResource BackgroundBrushConverter}"
ConverterParameter="{Staticresource MyArray}" />