3

今天在Nerd Plus Art博客上,有一篇关于为箭头创建 WPF 资源的帖子,作者经常使用该资源。我有一个带有后退和前进按钮的辅助项目,所以我认为左箭头和右箭头在这些按钮上会很好用。

我将LeftArrowRightArrowGeometries 添加到我的应用程序资源中,然后将它们用作按钮的内容:

<Application x:Class="Notes.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Views/MainWindow.xaml">
    <Application.Resources>
        <Geometry x:Key="RightArrow">M0,0 L1,0.5 0,1Z</Geometry>
        <Geometry x:Key="LeftArrow">M0,0.5 L1,1 1,0Z</Geometry>
    </Application.Resources>
</Application>

<Button x:Name="BackButton"
    Padding="5,5,5,5"
    Command="{x:Static n:Commands.GoBackCommand}">
    <Path Data="{StaticResource LeftArrow}" Width="10" Height="8"
        Stretch="Fill" Fill="Black"/>
    </Button>
<Button x:Name="ForwardButton"
    Padding="5,5,5,5"
    Command="{x:Static n:Commands.GoForwardCommand}">
    <Path Data="{StaticResource RightArrow}" Width="10" Height="8"
        Stretch="Fill" Fill="Red" />
</Button>

这行得通,除了无论按钮是否启用,箭头都被绘制为黑色。所以,我创建了一个ValueConverter从 abool到 a Brush

class EnabledColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        CultureInfo culture)
    {
        bool b = (bool)value;
        return b ? Brushes.Black : Brushes.Gray;
    }

    public object ConvertBack(object value, Type targetType, object parameter,
        CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

(我意识到我可能应该使用系统颜色而不是硬编码的黑色和灰色,但我只是想让这个工作,首先。)

我修改了 的Fill属性Path以使用我的转换器(我在应用程序的资源中创建):

<Path Data="{StaticResource LeftArrow}" Width="10" Height="8"
    Stretch="Fill"
    Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=IsEnabled, Converter={StaticResource EnabledColorConverter}}"/>

不幸的是,这不起作用,我不知道为什么。当我运行它时,根本没有绘制箭头。我在 Visual Studio 中检查了输出窗口,没有显示绑定错误。bool我还根据是否应启用按钮验证了转换器中的值是否正确。

如果我将Path背面更改为 a (并以与 相同的方式TextBlock绑定其属性),则文本始终以黑色绘制。ForegroundPath.Fill

难道我做错了什么?为什么Brush我的转换器返回的不用于Path在按钮中呈现?

4

3 回答 3

3

对于这种 UI 状态更新,请尝试改用触发器;它将使您免于编写值转换器,并且编写起来要短得多。

试试这个:

<Application x:Class="Notes.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Views/MainWindow.xaml">
    <Application.Resources>
        <Geometry x:Key="RightArrow">M0,0 L1,0.5 0,1Z</Geometry>
        <Geometry x:Key="LeftArrow">M0,0.5 L1,1 1,0Z</Geometry>

         <!-- Base Arrow Style, with a trigger to toggle it Gray when its parent button is disabled -->
        <Style x:Key="ArrowStyle" TargetType="Path">
            <Setter Property="Width" Value="10"/>
            <Setter Property="Height" Value="8"/>
            <Setter Property="Stretch" Value="Fill"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=IsEnabled}" Value="False">
                    <Setter Property="Fill" Value="Gray"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>

        <!-- Left Arrow Style, with the Left Arrow fill and data -->
        <Style x:Key="LeftArrowStyle" BasedOn="{StaticResource ArrowStyle}" TargetType="Path">
            <Setter Property="Fill" Value="Black"/>
            <Setter Property="Data" Value="{StaticResource LeftArrow}"/>
        </Style>

        <!-- Right Arrow Style, with the Right Arrow fill and data -->
        <Style x:Key="RightArrowStyle" BasedOn="{StaticResource ArrowStyle}" TargetType="Path">
            <Setter Property="Fill" Value="Red"/>
            <Setter Property="Data" Value="{StaticResource RightArrow}"/>
        </Style>
    </Application.Resources>

    <Button x:Name="BackButton" Padding="5,5,5,5" IsEnabled="False">
        <Path Style="{StaticResource LeftArrowStyle}"/>
    </Button>
    <Button x:Name="ForwardButton" Padding="5,5,5,5">
        <Path Style="{StaticResource RightArrowStyle}"/>
    </Button>
</Application>

然后,分别为左箭头和右箭头设置默认填充 LeftArrowStyle 和 RightArrowStyle。如果您在 Path 本身上设置它,则该值将优先并覆盖样式或其触发器可能执行的任何操作。基本样式 ArrowStyle 包含一个绑定到父按钮的 DataTrigger - 只要 IsEnabled 为假,它就会触发,并将路径的填充更改为灰色。

于 2009-06-04T13:29:33.443 回答
2

为什么不将路径的填充绑定到按钮的前景?

<Button x:Name="BackButton"
    Padding="5,5,5,5"
    Command="{x:Static n:Commands.GoBackCommand}">
    <Path Data="{StaticResource LeftArrow}" Width="10" Height="8"
        Stretch="Fill" Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=Foreground"/>
    </Button>
于 2009-06-04T13:27:45.787 回答
0

您的代码基本上可以工作。我认为您的静态资源可能是错误的,因为您没有指定从哪里获取转换器。

你可能需要

<Window.Resources>
    <conv:EnabledColorConverter x:Key="brushConv" />
</Window.Resources>

然后将您的绑定指定为:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=IsEnabled, Converter={StaticResource brushConv}}
于 2009-06-04T12:06:36.373 回答