2009-06-04 40 views
2

在今天的博客Nerd Plus Art上,有一篇关于创建箭头的WPF资源的文章,作者经常使用它。我有一个具有后退和前进按钮的项目,所以我认为左右箭头在这些按钮上效果很好。为笔刷创建一个WPF ValueConverter

我加入了LeftArrowRightArrow几何形状,以我的应用程序的资源,然后把他们当作按钮的内容:

<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从去一个boolBrush

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(); 
    } 
} 

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

我修改了PathFill财产使用我的转换器(这是我的应用程序的资源范围内创建):

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

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

如果我改变PathTextBlock(及其Foreground属性绑定在相同的方式为Path.Fill),文本总是以黑色绘制。

我做错了什么?为什么我的转换器返回的Brush未用于渲染按钮中的Path

+0

不知道为什么你的代码是不工作的,但我会用样式触发这个...... – Will 2009-06-04 12:04:23

回答

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> 
+0

这将是一个更直接的方法,它的工作原理。谢谢您的帮助。 :) – Andy 2009-06-04 16:17:32

0

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

你可能需要

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

,然后指定你的绑定:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=IsEnabled, Converter={StaticResource brushConv}} 
+0

我在Application.Resources定义的转换器 - 我只是没有在代码中包括它上面。对困惑感到抱歉。 – Andy 2009-06-04 16:14:20

2

对于这种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填充,左,右箭头。如果您将其设置在路径本身上,则该值将优先并覆盖样式或其触发器可能执行的任何操作。基础样式ArrowStyle包含绑定到父按钮的DataTrigger - 只要IsEnabled为false就会触发,并将Path的填充更改为Gray。

+0

我想我会去与ppx的方法绑定到Button的前景直接看起来像一个更好的方法。不过,谢谢你提供的信息丰富的答案。 :) – Andy 2009-06-04 16:18:21