Pergunta

No Nerd Além disso Art blog hoje, houve um post sobre a criação de recursos WPF para setas, que os usos autor freqüentemente. Eu tenho um projeto paralelo que tem botões Avançar e Voltar, então eu pensei que o setas Esquerda e Direita seria um grande trabalho nesses botões.

Eu adicionei as geometrias LeftArrow e RightArrow aos recursos da minha aplicação, e, em seguida, usou-os como o conteúdo dos botões:

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

Isso funcionou, exceto que as setas foram desenhadas em preto, independentemente do botão foi ativado ou não. Então, eu criei um ValueConverter para ir de um bool a um 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();
    }
}

(eu percebo que eu provavelmente deve usar cores do sistema, em vez de codificado preto e cinza, mas eu só queria começar este trabalho, em primeiro lugar.)

Eu modifiquei a propriedade Fill do Path usar meu conversor (que eu criei dentro dos recursos do aplicativo):

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

Infelizmente, isso não funciona, e eu não sei porquê. Quando eu executá-lo, a seta não é desenhada em tudo. Eu verifiquei a janela de saída no Visual Studio, e nenhum erro de ligação foram exibidos. Eu também verificou que o bool é o valor correto no conversor, com base no se o botão deve ser habilitado ou não.

Se eu mudar a parte traseira Path a um TextBlock (e vincular sua propriedade Foreground da mesma maneira como Path.Fill), o texto é sempre desenhado em preto.

Estou fazendo algo errado? Porque é que a Brush devolvido pelo meu conversor não usado para processar o Path no botão?

Foi útil?

Solução

Por que não apenas ligam o preenchimento do seu caminho para o primeiro plano do botão?

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

Outras dicas

Para este tipo de atualizações de estado de interface do usuário, tente usar gatilhos vez; ele vai te salvar de escrever um conversor de valor, e é muito mais curto para escrever.

Tente isto:

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

Em seguida, defina o seu preenchimento padrão no LeftArrowStyle e RightArrowStyle, para as setas esquerda e direita, respectivamente. Se você configurá-lo no próprio caminho, então esse valor teria precedência e substituir qualquer coisa que um estilo ou o seu gatilho pode fazer. O estilo de base, ArrowStyle, contém uma DataTrigger ligado ao botão de pai -. Ele é acionado sempre que IsEnabled é falsa, e muda de preenchimento do Path to Grey

Seu código funciona essencialmente. Eu acho que seu recurso estático pode estar errado quanto a sua não especificando onde isso está ficando o conversor.

Você provavelmente precisará

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

e, em seguida, especifique a sua ligação como:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=IsEnabled, Converter={StaticResource brushConv}}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top