2009-06-04 1 views
2

В блоге Nerd Plus Art было опубликовано сообщение о создании ресурсов WPF для стрелок, которые автор часто использует. У меня есть боковой проект с кнопками «Назад» и «Вперед», поэтому я подумал, что стрелки влево и вправо будут отлично работать на этих кнопках.Создание WPF ValueConverter для кисти

Я добавил LeftArrow и RightArrow геометрий ресурсов моего приложения, а затем использовали их в качестве содержания кнопок:

<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, чтобы пойти от bool к 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}}"/> 

к сожалению, это не вес ork, и я не уверен, почему. Когда я его запускаю, стрелка вообще не рисуется. Я проверил окно «Вывод» в Visual Studio, и никаких ошибок привязки не было. Я также подтвердил, что bool является правильным значением в конвертере, в зависимости от того, должна ли кнопка включаться или нет.

Если я изменяю Path спиной к TextBlock (и связать его свойство Foreground таким же образом, как Path.Fill), текст всегда рисуется в черном цвете.

Я что-то не так? Почему Brush, возвращенный моим конвертером, не используется для визуализации Path в кнопке?

+0

не уверен, почему ваш код не работает, но я бы использовал триггеры стиля для этого ... – Will

ответ

2

Почему не просто связать заливку вашего пути к Foreground Баттона?

<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

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

2

Для этого обновления состояния пользовательского интерфейса попробуйте вместо этого использовать триггеры; это избавит вас от написания конвертера значений, и писать намного короче.

Попробуйте это:

<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 является ложным, и изменяет Fill на Grey.

+0

Я думаю, что я собираюсь пойти с подходом ppx к привязке к Forefront Button непосредственно, кажется, лучший подход. Тем не менее, спасибо за очень информативный ответ. :) – Andy

 Смежные вопросы

  • Нет связанных вопросов^_^