В WPF у меня есть ListBox со списком, состоящим из UserControls. Элементы управления предназначены для перехода на различные экраны приложения. Каждый UserControl (называемый NavigationButton) имеет значок и текст. Значки в основном представляют собой комбинации нескольких объектов Path, поэтому каждый значок является собственным UserControl, и они отображаются с помощью ContentPresenter. Я хочу иметь возможность анимировать цвет значка в зависимости от разных состояний экрана, но попробовал множество опций и не смог этого сделать.Animate DependencyProperty в UserControl, отображаемом через ContentPresenter
Вот урезанная версия NavigationButton:
<DockPanel Margin="12,0,12,0">
<!-- Icon -->
<ContentPresenter x:Name="Content_Icon" Content="{Binding}" Width="20"/>
<!-- Text -->
<Grid Margin="9,0,0,0">
<TextBlock x:Name="TextBlock_Text" Text="{Binding ScreenName, Converter={StaticResource StringToStringUpperConverter}}" VerticalAlignment="Center"
FontSize="15" Foreground="#FFF2F2F2" />
</Grid>
В принципе, мне нужно анимировать свойство на ContentPresenter, но не знаю, как получить к нему доступ.
Вот ListBox хостинг в NavigationButtons:
<ListBox DockPanel.Dock="Top" ItemsSource="{Binding ScreenViewModels}"
SelectedItem="{Binding SelectedScreenViewModel}">
<ListBox.ItemTemplate>
<DataTemplate>
<my:NavigationButton/>
</DataTemplate>
</ListBox.ItemTemplate>
Я создал базовый UserControl (так называемый IconBaseControl), что все эти иконы UserConrols может унаследовать. У базового элемента управления есть функция DependencyProperty Brush, называемая IconFill. Части дорожек на иконке, которая может изменить связаны с этим свойством:
<Path Data="<data>" Fill="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type my:IconBaseControl}}, Path=IconFill}"
Я знаю, привязка работает правильно, потому что цвета изменяются при изменении цвета по умолчанию на UserControl. В идеале я хочу использовать VisualStateManager, потому что будет много разных состояний. Итак, у меня есть VisualStateManager в NavigationButton, UserControl, содержащий ContentPresenter, на котором размещается значок (все UserControls, которые наследуют IconBaseControl), называемый Content_Icon. Я пытался что-то подобное в одном из состояний:
<VisualState x:Name="Deselected">
<Storyboard>
<ColorAnimation Storyboard.TargetName="TextBlock_Text" Storyboard.TargetProperty="Foreground.Color"
To="#FF5e5e5e" Duration="0"/>
<ColorAnimation Storyboard.TargetName="Content_Icon" Storyboard.TargetProperty="IconFill"
To="#FF5e5e5e" Duration="0"/>
</Storyboard>
</VisualState>
Но я получаю следующее сообщение об ошибке:
InvalidOperationException: Не удается разрешить все ссылки на недвижимость в пути свойства «IconFill». Убедитесь, что применимые объекты поддерживают свойства.
Я также попытался связывание свойства раскадровки с чем-то вроде этого:
Storyboard.TargetProperty="(IconBaseControl.IconFill)
Но получить эту ошибку:
IconBaseControl не поддерживается в проекте Windows Presentation Foundation (WPF).
Я также пытался испортить код позади, но не могу понять, как преобразовать ContentPresenter в IconBaseControl. Я понял, что свойство ContentTemplate будет способом, но это ничего.
Любые предложения о том, как оживить это свойство? Открыто для почти чего угодно :) Я кодирую в VB.Net, но любые предложения C# тоже хороши.
Заранее спасибо.
EDIT: Включены коды NavigationButton
Спасибо за ответ! Единственная проблема заключается в том, что я использую ContentPresenter в элементе управления для отображения другого значка в зависимости от DataContext элемента управления. Список содержит привязку к списку режимов просмотра, каждый из которых представляет собой другой экран. Поэтому каждый экран должен иметь свой собственный значок. Вот в чем проблема: у меня возникают трудности с доступом к любым свойствам ContentPresenter. Вот почему я попытался сделать их одинаковыми, используя наследование, но это ничуть не вызвало меня. – Riggs
Мне сложно визуализировать ваш дизайн, но иногда использование конвертеров полезно при необходимости внесения сложных изменений в пользовательский интерфейс, например значок. Итак, что вы можете сделать, это привязать источник изображения к значению в ViewModel (будет работать enum). И затем используйте конвертер на этом привязке, который принимает это значение перечисления и возвращает правильный значок. Если вы хотите добавить больше кода, я мог бы помочь больше. – baueric
Или у вас может быть ссылка на источник изображения следующим образом: Source = "{Binding Converter = {StaticResource MyIconConverter}}". Что это будет сделано, так это передать весь DataContext в конвертер. Затем вы можете просто вернуть правильный значок в зависимости от типа класса DataContext. – baueric