1

WPF には、UserControls で構成されるリストを含む ListBox があります。コントロールは、アプリケーション内のさまざまな画面に移動するためのものです。各 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>

これらのすべてのアイコン UserConrolls が継承できる基本 UserControl (IconBaseControl と呼ばれる) を作成しました。基本コントロールには、IconFill と呼ばれる Brush DependencyProperty があります。変更可能なアイコン上のパスの部分は、このプロパティにバインドされています。

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

UserControl のデフォルトの色を変更すると色が変わるため、バインドが正しく機能していることがわかります。理想的には、さまざまな状態が存在するため、VisualStateManager を使用したいと考えています。したがって、NavigationButton に VisualStateManager があります。これは、Content_Icon と呼ばれる、アイコン (IconBaseControl を継承するすべての UserControls) をホストする ContentPresenter を含む UserControl です。ある州で次のようなことを試しました。

<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#の提案も問題ありません。

前もって感謝します。

編集: NavigationButton のコードが含まれています

4

1 に答える 1

1

WPF コントロールのサブクラスを作成すると面倒になる可能性があり、非常に高度な問題でない限り必要ないことがわかりました。私の意見では、 UserControl の子として IconBaseControl を作成することは、あなたのシナリオではやり過ぎです。

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 という値へのバインディングに基づいて変化することに注意してください。したがって、この時点で、依存関係プロパティとして IsSelected ブール値が公開されている IconControlViewModel.cs という ViewModel を作成する必要があります。

最後に、これらのナビゲーション ボタンを含むビュー:

<UserControl>

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

</UserControl>

ItemsSource リストに IconControlViewModel が表示されたときに、ItemsControl に何をレンダリングするかを指示する DataTemplate に注意してください。これは、MVVM パターンを使用して設計する方法です。これがお役に立てば幸いです。私の回答について明確にする必要があるかどうか、またはそれが間違っているかどうかをお知らせください。

乾杯、エリック

于 2013-10-04T17:14:55.117 に答える