1

在 WPF 中,我有一个 ListBox,其中包含由 UserControls 组成的列表。这些控件旨在导航到应用程序中的不同屏幕。每个 UserControl(称为 NavigationButton)都有一个图标和文本。这些图标大多是多个 Path 对象的组合,因此每个图标都是它自己的 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 上的属性设置动画,但不知道如何访问它。

这是承载 NavigationButtons 的 ListBox:

        <ListBox DockPanel.Dock="Top" ItemsSource="{Binding ScreenViewModels}" 
             SelectedItem="{Binding SelectedScreenViewModel}">

        <ListBox.ItemTemplate>
            <DataTemplate>
                <my:NavigationButton/>
            </DataTemplate>
        </ListBox.ItemTemplate>

我创建了一个基本 UserControl(称为 IconBaseControl),所有这些图标 UserConrols 都可以继承。基本控件有一个 Brush DependencyProperty,称为 IconFill。图标上可以更改的路径部分绑定到此属性:

<Path Data="<data>" Fill="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type my:IconBaseControl}}, Path=IconFill}"

我知道绑定工作正常,因为当我更改 UserControl 上的默认颜色时颜色会发生变化。理想情况下,我想使用 VisualStateManager,因为会有很多不同的状态。因此,我在 NavigationButton 上有一个 VisualStateManager,该 UserControl 包含承载图标的 ContentPresenter(所有继承 IconBaseControl 的 UserControl),称为 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)

但是得到这个错误:

Windows Presentation Foundation (WPF) 项目不支持 IconBaseControl。

我也尝试过在后面的代码中弄乱,但无法弄清楚如何将 ContentPresenter 转换为 IconBaseControl。我认为 ContentTemplate 属性将是要走的路,但它什么都不是。

有关如何为该属性设置动画的任何建议?对几乎任何东西都开放 :) 我在 VB.Net 中编码,但任何 C# 建议也很好。

提前致谢。

编辑:包含 NavigationButton 的代码

4

1 回答 1

1

我发现创建 WPF 控件的子类可能会变得混乱,并且没有必要,除非它是一个非常高级的问题。在我看来,将 IconBaseControl 创建为 UserControl 的子项在您的场景中是多余的。

假设您使用的是 MVVM,这是我的建议:将 IconBaseControl 创建为普通的 UserControl。只需创建一个带有 IconControl.xaml.cs 代码的 IconControl.xaml 文件,就像您创建任何其他视图一样。

以下是您在 IconControl 中拥有的示例:

<UserControl>
    <Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.Style>
        <Style>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsSelected}" Value="True">
                    <DataTrigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="#FF5e5e5e" Duration="0:0:0" />
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.EnterActions>
                    <DataTrigger.ExitActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="White" Duration="0:0:0" />
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.ExitActions>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Style>

    <Image Source="Icon.jpeg" />

    <TextBlock Text="{Binding PageName}" Grid.Column="1" />

</Grid>
</UserControl>`

请注意,周围网格的背景将根据与 DataContext 上名为 IsSelected 的值的绑定而改变。因此,此时您需要创建一个名为 IconControlViewModel.cs 的 ViewModel,它具有作为依赖属性公开的 IsSelected 布尔值。

最后是包含这些导航按钮的视图:

<UserControl>

    <ItemsControl ItemsSource="{Binding ListOf_IconControlViewModels}">
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type IconControlViewModel}">
                <local:IconView />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

</UserControl>

请注意 DataTemplate,它告诉 ItemsControl 当它在 ItemsSource 列表中看到 IconControlViewModel 时要呈现什么。这就是我使用 MVVM 模式设计它的方式。我希望这会有所帮助,并让我知道您是否需要澄清我的答案,或者它已经过时了。

干杯,埃里克

于 2013-10-04T17:14:55.117 回答