Ieri al termine della mia sessione ai Community Days 2008 Nicolò ha proposto un “intrigante” quesito: In breve: l’obiettivo è quello di cambiare il colore di sfondo di alcune labels in base al testo inserito in una textbox, gestendo il tutto all’interno di un unico style implicito condiviso da tutte le labels.
Alla fine, ragionandoci un attimo, sono giunto a questa soluzione che aggira l’impossibilità di usare binding sulla proprietà Value della classe DataTrigger usando un MultiTrigger alimentato con:

  • il valore contenuto della textbox.
  • Il valore della proprietà da confrontare attraverso RelativeSource  che in questo esempio anzichè usare la solita proprietà Tag usa una custom Attached Property così che la soluzione sia applicabile anche quando Tag non è disponibile.

Questo è il codice del converter e la definizione dell’Attached Property

namespace WPF_ParamOnTrigger
{
  public class MyConverter:IMultiValueConverter
  {
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
      string text = values[0].ToString();
      string tag = values[1].ToString();
      return (text == tag);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
      throw new NotImplementedException();
    }
  }

  public static class Element
  {
    public static readonly DependencyProperty IdProperty =DependencyProperty.RegisterAttached("Id", typeof(string), typeof(Element));

    public static string GetId(DependencyObject d)
    {
      return (string)d.GetValue(IdProperty);
    }

    public static void SetId(DependencyObject d, string value)
    {
      d.SetValue(IdProperty, value);
    }   
  }

Questo è invece lo XAML corrispondente:

<Window x:Class="WPF_ParamOnTrigger.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:l="clr-namespace:WPF_ParamOnTrigger"
    Title="Window1" Height="317" Width="495">
  <Window.Resources>
    <!--Converter-->
    <l:MyConverter x:Key="TriggerConverterKey" />
    
    <!--Label Style-->
    <Style TargetType="Label">
      <Setter Property="BorderBrush" Value="Black" />
      <Setter Property="BorderThickness" Value="1" />
      <Setter Property="Background" Value="Beige" />
      <Setter Property="Margin" Value="5" />
      <Style.Triggers>
        <DataTrigger Value="True">
          <DataTrigger.Binding>
            <MultiBinding Converter="{StaticResource TriggerConverterKey}"  >
              <Binding ElementName="txtName" Path="Text" />
              <Binding RelativeSource="{RelativeSource Self}" Path="(l:Element.Id)" />
            </MultiBinding>
          </DataTrigger.Binding>
          <Setter Property="Background" Value="Yellow" />          
        </DataTrigger>
      </Style.Triggers>
    </Style>
    
  </Window.Resources>
    <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="60" />
      <RowDefinition Height="227*" />
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal">
      <Label l:Element.Id="d1">Dept1</Label>
      <Label l:Element.Id="d2">Dept2</Label>
      <Label l:Element.Id="d3">Dept3</Label>
      <Label l:Element.Id="d4">Dept4</Label>
    </StackPanel>
    <TextBox Grid.Row="1" Margin="13.12,17,0,0" Width="199" Height="22" x:Name="txtName" />
  </Grid>
</Window>

Bravo, Nicolò, ottima domanda, ti meriti un libro su NHibernate! smile_wink

Technorati Tags: ,,