【问题标题】:Setting VisualState on ItemsControl item Templates在 ItemsControl 项模板上设置 VisualState
【发布时间】:2012-07-03 00:24:18
【问题描述】:

我有一个 ItemsControl 和一个绑定到数据项的 ItemTemplate。 ItemTemplate 相当复杂,我在其中添加了一些视觉状态,以便我可以更改它的外观。

我希望能够在 ItemsControl 之外发生的事件上将所有项目 VisualState 切换到我选择的另一个状态。

我该怎么做呢?我试过使用 VisualStateManager.SetState,但这依赖于一个控件,而不是一个模板,这似乎是我可以通过 WaveItems.ItemContainerGenerator.ContainerFromIndex(i) 获得的所有内容。

问候

特里斯坦

编辑:

这是我的各个项目的数据模板。如果您注意到我设置的触发器,它会处理模板本身的 MouseEnter / MouseLeave。我想将这些连接到 ItemsControl MouseEnter / MouseLeave,而无需编写任何代码。有没有办法做到这一点?

    <DataTemplate x:Key="LineTemplate">
    <Grid x:Name="LineGrid" HorizontalAlignment="Left" Height="500" VerticalAlignment="Center" Width="3">

        <VisualStateManager.CustomVisualStateManager>
            <ei:ExtendedVisualStateManager/>
        </VisualStateManager.CustomVisualStateManager>

        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="VisualStateGroup">
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0"/>
                </VisualStateGroup.Transitions>
                <VisualState x:Name="Expanded">
                    <Storyboard>
                        <DoubleAnimation Duration="0:0:1" By="-100" Storyboard.TargetProperty="(Line.Y2)" Storyboard.TargetName="lineTop"/>
                        <DoubleAnimation Duration="0:0:1" By="100" Storyboard.TargetProperty="(Line.Y2)" Storyboard.TargetName="lineBottom"/>
                        <DoubleAnimation Duration="0:0:1" To="0.5" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="lineTop" d:IsOptimized="True"/>
                        <DoubleAnimation Duration="0:0:1" To="0.25" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="lineBottom" d:IsOptimized="True"/>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Normal">
                    <Storyboard>
                        <DoubleAnimation Duration="0:0:1" To="0" Storyboard.TargetProperty="(Line.Y2)" Storyboard.TargetName="lineTop" d:IsOptimized="True"/>
                        <DoubleAnimation Duration="0:0:1" To="{Binding BottomValue}" Storyboard.TargetProperty="(Line.Y2)" Storyboard.TargetName="lineBottom" d:IsOptimized="True"/>
                        <DoubleAnimation Duration="0:0:1" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="lineTop" d:IsOptimized="True"/>
                        <DoubleAnimation Duration="0:0:1" To="0.495" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="lineBottom" d:IsOptimized="True"/>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="ExpandedHighlight"/>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseEnter" >
                <ei:GoToStateAction x:Name="Expand" StateName="Expanded"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="MouseLeave">
                <ei:GoToStateAction x:Name="Collapse" StateName="Normal"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>

        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Line Grid.Row="0" x:Name="lineTop" VerticalAlignment="Bottom" StrokeThickness="3" Stroke="{Binding Brush}" Y1="{Binding TopValue}" Y2="0" RenderTransformOrigin="0.5,0.5">
            <Line.RenderTransform>
                <CompositeTransform ScaleY="1"/>
            </Line.RenderTransform>
        </Line>

        <Line Grid.Row="1" x:Name="lineBottom" VerticalAlignment="Top" StrokeThickness="3" Stroke="{Binding Brush}" Y1="0" Y2="{Binding BottomValue}" RenderTransformOrigin="0.5,0.5" Opacity="0.5">
            <Line.RenderTransform>
                <CompositeTransform ScaleY="1"/>
            </Line.RenderTransform>
        </Line>
    </Grid>
</DataTemplate>

我也尝试过使用以下绑定: SourceObject="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}"

但这会显示一条消息:“silverlight 项目中不支持类型”。

【问题讨论】:

  • 你最好提供一些代码。

标签: c# wpf itemscontrol


【解决方案1】:

固定:

            <i:Interaction.Triggers>
            <i:EventTrigger
                SourceObject="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ItemsControl}}"
                EventName="MouseEnter">
                <ei:GoToStateAction x:Name="Expand" StateName="Expanded"/>
            </i:EventTrigger>
            <i:EventTrigger 
                SourceObject="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ItemsControl}}"
                EventName="MouseLeave">
                <ei:GoToStateAction x:Name="Collapse" StateName="Normal"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>

【讨论】:

    【解决方案2】:

    Thomas Danemar's Blog 中有一个类的示例来保持和切换VisualState。它是通过将 VisualState 绑定到 ViewModel 中的附加属性来实现的,他们只需将其设置为期望值。 你甚至可以绑定TwoWay模式。

    【讨论】:

    • 好吧,这听起来好像可行,但远非理想,因为我真的不想直接访问这些项目。我希望使用绑定到触发器的隧道事件。
    • 这篇博文似乎专注于为 UserControl 实现这一点。我只有一个模板。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多