【问题标题】:XAML Style Won't Apply Until EventTrigger Command CompletesXAML 样式在 EventTrigger 命令完成之前不会应用
【发布时间】:2015-05-20 16:08:02
【问题描述】:

我有一个定义自定义 ControlTemplate 的 ListBox。选中的item有改变背景和前景的样式,样式基本有效。但是,我想介绍一种在选择更改时显示模式消息框的行为,询问用户是否真的要选择不同的项目。我已经实现了一个 ICommand 来执行此操作,在下面的代码中显示为 AreYouSureCommand。

问题是在显示模式消息框时,所选项目的背景样式已更改,但前景未更改。一旦我关闭模式消息框,前景色就会改变。我没有包含 ICommand 的代码,因为它有点令人费解,但希望在执行时使用 ShowDialog 打开一个窗口就足够了。

谁能解释为什么我的背景颜色会改变,而前景色却没有?

<ListBox x:Name="SubMenu" ItemsSource="{Binding MyItems}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=DisplayName}"
                        Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=ContentControl}}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.Resources>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Border x:Name="MainBorder">
                            <ContentControl x:Name="Presenter">
                                <ContentPresenter />
                            </ContentControl>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <!-- Setter on MainBorder applies before AreYouSureCommand completes -->
                                <Setter TargetName="MainBorder" Property="Background" Value="Red" />
                                <!-- Setter on Presenter applies after AreYouSureCommand completes -->
                                <Setter TargetName="Presenter" Property="Foreground" Value="Green" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.Resources>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <i:InvokeCommandAction Command="{Binding AreYouSureCommand}"
                                    CommandParameter="{Binding SelectedItem, ElementName=SubMenu}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListBox>

【问题讨论】:

  • 如果在 XAML 中更改顺序会发生相反的情况?
  • 有趣的想法,但没有 - 如果我颠倒顺序,同样的事情会发生 - 背景颜色会改变,但前景不会改变,直到我关闭模式消息框。
  • 我猜您正在将前景设置为数据模板中的特定值,而触发器无法更改它。尝试删除 Foreground 属性并将其作为默认样式添加到 ListBoxItem 的样式标记中?

标签: c# .net wpf xaml


【解决方案1】:

我最终找到了解决方案。基本上,我对IsSelected 属性使用另一个setter 将ListViewItemIsSelected 的值推送到视图模型上。然后我使用DataTrigger 而不是常规 Trigger 来设置所选样式,并将触发器绑定到视图模型上的 IsSelected 属性而不是 ListViewItem 本身的属性。我真的不知道为什么会这样 - 实际上应该没有什么不同,但它确实有效。

感谢 Juan 和 Ben 的 cmets。

<ListBox x:Name="SubMenu" ItemsSource="{Binding MyItems}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=DisplayName}"
                        Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=ContentControl}}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.Resources>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Border x:Name="MainBorder">
                            <ContentControl x:Name="Presenter">
                                <ContentPresenter />
                            </ContentControl>
                        </Border>
                        <ControlTemplate.Triggers>
                            <DataTrigger Binding="{Binding IsSelected}" Value="True">
                                <Setter TargetName="MainBorder" Property="Background" Value="Red" />
                                <Setter TargetName="Presenter" Property="Foreground" Value="Green" />
                            </DataTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.Resources>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <i:InvokeCommandAction Command="{Binding AreYouSureCommand}"
                                    CommandParameter="{Binding SelectedItem, ElementName=SubMenu}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListBox>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-17
    • 1970-01-01
    相关资源
    最近更新 更多