0

我是一名进入 .Net 的 Access 开发人员,我有一个 WPF 项目。由于我习惯于 Access 中的子表单,因此我创建了用户控件以这种方式进行操作(本身可能是一个问题,但我目前还没有解决这个问题)。

这个特定的用户控件(子窗体)有几个列表框,这些列表框绑定到后面代码中的对象(VB——我也没有参与那个辩论;我熟悉 VBA)。这些列表框绑定到一个名为“IsAssigned”的布尔值。我创建了一种样式,根据该值将这些列表框中的项目更改为绿色或红色。这是有效的。

然后我想更改该值以覆盖窗口的突出显示行为并了解 SystemColors.HighlightColor 和 ControlBrushKey。问题是我希望 HighlightColor 和 ControlBrushKey 颜色取决于“IsAssigned”值。除非我错过了什么,否则我显然无法嵌套触发器。在下面的代码中,我将高亮值设置为绿色只是为了说明我对此的理解。

So what I want is that when an item is selected, the text is bolded, with a black border, and maintains a solid color of green or red depending on the "IsAssigned" value. 当同一个项目是突出显示的项目时,我真的希望前景色为白色,并且可能有更厚的边框。

温柔点——我在很多方面都是菜鸟。

<UserControl.Resources>
    <Style TargetType="{x:Type ListBoxItem}" x:Key="ColorTrueAndFalse">
        <Style.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightColor}" Color="Green" />
            <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Green" />
        </Style.Resources>
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="true">
                <Setter Property="FontWeight" Value="Bold" />
                <Setter Property="BorderBrush" Value="Black" />
            </Trigger>
            <DataTrigger Binding="{Binding IsAssigned}" Value="True">
                <Setter Property="Background">
                    <Setter.Value>
                        <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
                            <GradientStop Color="LightGreen" Offset="0" />
                            <GradientStop Color="Green" Offset="1" />
                            <GradientStop Color="LawnGreen" Offset="2" />
                        </LinearGradientBrush>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsAssigned}" Value="False">
                <Setter Property="Background">
                    <Setter.Value>
                        <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
                            <GradientStop Color="LightCoral" Offset="0.5" />
                            <GradientStop Color="Coral" Offset="1" />
                            <GradientStop Color="Red" Offset="2" />
                        </LinearGradientBrush>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>
4

2 回答 2

2

the DataContextof theListBoxItem不同于 the one of theListBox本身。在's 样式中使用时,您没有使用与 the 相同的样式,因此{Binding IsAssigned}您找不到该属性。ListBoxItemDataContextListBox

这可以通过使用相对绑定轻松解决- 例如:

<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}, Path=DataContext.IsAssigned}" Value="true">

这会尝试绑定到 ListBoxItems 的父级。它沿着 Visual Tree 向上直到找到 ListBox 并尝试使用前者的DataContext属性来查找 IsAssigned。

所以一个完整的解决方案看起来像这样:

<Style.Triggers>
    <Trigger Property="IsSelected" Value="true">
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="BorderBrush" Value="Black" />
    </Trigger>
    <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}, Path=DataContext.IsAssigned}" Value="true">
        <Setter Property="Background">
          ....
        </Setter>
    </DataTrigger>

更新- 突出显示:

首先注意高光画笔的名称HighlightBrushKey不是你写的:

<Style.Resources>
    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Green" />

第二 - 而不是Trigger您使用的,使用它DataTrigger来更改所选项目的属性:

<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Self}}" Value="True">
    <Setter Property="FontWeight" Value="Bold" />
    <Setter Property="BorderBrush" Value="Black" />
</DataTrigger>
于 2012-12-30T08:39:03.227 回答
1

好吧,经过大量拔掉我剩下的小头发,并从 Blachshma 那里得到了一些正确方向的指示,我想出了一个解决方案。它主要基于此处找到的标记。

HighlightBrushKey 和 ControlBrushKey 让我很伤心——我无法让它们识别数据触发器已经设置的基础颜色。我可以将其设置为静态颜色,但没有任何动态。如果投入更多时间,这可能会奏效。相反,我使用边框来设置数据触发器中的颜色,并更改任何选定项目的字体和不透明度。即使在一个列表框中选择了一个项目并移开以选择另一个列表框中的另一个项目后,边框颜色仍然保持不变,这正是我想要的。

这是我的 XAML(为简洁起见,省略了某些细节):

<UserControl.Resources>
    <Style TargetType="{x:Type ListBoxItem}" x:Key="BorderTrueAndFalse">
        <Style.Resources>
            <LinearGradientBrush x:Key="TrueBrush" EndPoint="1,0.5" StartPoint="0,0.5">
                ...
            </LinearGradientBrush>
            <LinearGradientBrush x:Key="FalseBrush" EndPoint="0,0.5" StartPoint="1,0.5">
                ...
            </LinearGradientBrush>
        </Style.Resources>
        <Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border  Name="Border" Padding="2" SnapsToDevicePixels="true">
                            <ContentPresenter />
                    </Border>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding IsAssigned}" Value="True">
                            <Setter TargetName="Border" Property="Background" Value="{StaticResource TrueBrush}"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding IsAssigned}" Value="False">
                            <Setter TargetName="Border" Property="Background" Value="{StaticResource FalseBrush}"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Self}}" Value="True">
                            <Setter Property="FontWeight" Value="Bold" />
                            <Setter Property="Foreground" Value="White"/>
                            <Setter Property="Opacity" Value=".8"/>
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

当然,我相信我对这里发生的事情只有 80% 的把握,但是这个过程让我对绑定、触发器、样式、模板以及为什么 Access 的东西开发得如此之快有了更深入的了解!也许有一天我会把文本设置为旋转、闪烁,然后起床做一个小跳汰机,但现在我是一个快乐的露营者。

于 2012-12-31T13:34:35.690 回答