Domanda

Sto cercando di lavorare con, e capire la gerarchia XAML per gli stili ... in modo semplice, una semplice casella di testo ... visto in tutto il luogo per come impostare il colore di sfondo "disabile", basato sul "IsEnabled" bandiera. Grande, ottenuto che.

Ora, voglio avere un'altra classe derivata da TextBox ... MyTextBox. Per questa classe, ho un immobile (non di dipendenza proprietà, quindi stavo usando DataTrigger). Quindi, voglio mantenere tutte le normali azioni TextBox che stavano lavorando, ma ora ottenere il nuovo trigger per aggiornare correttamente il colore di sfondo per qualche altro colore .. Quindi, ecco quello che ho. tanto per chiarire, tutte le mie risorse statiche per i colori sono PENNELLI SOLIDO ...

<Style TargetType="TextBox" >
  <Setter Property="FontFamily" Value="Courier New" />
  <Setter Property="FontSize" Value="12" />
  <Setter Property="Foreground" Value="{StaticResource MyForeground}" />
  <Setter Property="Background" Value="{StaticResource MyBackground}" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="TextBox">
        <Border Name="Bd" BorderThickness="{TemplateBinding BorderThickness}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            Background="{TemplateBinding Background}" 
            SnapsToDevicePixels="true">

            <ScrollViewer Name="PART_ContentHost" 
                Background="{TemplateBinding Background}" 
                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
        </Border>

        <ControlTemplate.Triggers>
          <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Background" Value="{StaticResource MyDisBackground}" />
            <Setter TargetName="PART_ContentHost" Property="Background" 
                 Value="MyDisBackground"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<!--  Now, my derived (or so I was hoping) style that just adds additional trigger -->
<Style TargetType="local:MyTextBox"  BasedOn="{StaticResource {x:Type TextBox}}" >
  <Style.Triggers>
    <DataTrigger Binding="{Binding Path=IsRequired}" Value="True">
      <Setter Property="Background" Value="{StaticResource RequiredBackground}" />
    </DataTrigger>
  </Style.Triggers>
</Style>

mi sto perdendo qualcosa di semplice?

È stato utile?

Soluzione

In primo luogo, la vostra DataTrigger sta guardando la DataContext del vostro MyTextBox (non il controllo stesso). Così sguardo al controllo, avresti bisogno di fare qualcosa di simile:

<DataTrigger Binding="{Binding Path=IsRequired, RelativeSource={RelativeSource Self}}" Value="True">
    <Setter Property="Background" Value="{StaticResource RequiredBackground}" />
</DataTrigger>

Ora che imposterà la proprietà MyTextBox.Background quando MyTextBox.IsRequired è vero. Ma i valori delle proprietà di dipendenza hanno una precedenza ordine . Così il sopra cambierà visivamente lo sfondo utilizzato come:

<local:MyTextBox />

Nel caso seguente non verrà usato il pennello RequiredBackground. Invece vedrete il pennello MyDisBackground:

<local:MyTextBox IsEnabled="False" />

In questo caso, il ScrollViewer.Background viene modificato in MyDisBackground e non più si lega alla proprietà MyTextBox.Background. Il MyTextBox.Background sarebbe ancora RequiredBackground, ma non è più da nessuna parte utilizzato.

Infine, nel caso seguente non verrà usato il pennello RequiredBackground.

<local:MyTextBox Background="Yellow" />

Qui, il valore locale (giallo) è al # 3 nella lista di precedenza, mentre il setter stile è al # 8.

Se si effettua la vostra proprietà una proprietà di dipendenza che il default è false, allora si potrebbe fare qualcosa di simile:

<Style TargetType="TextBox" >
  <Setter Property="FontFamily" Value="Courier New" />
  <Setter Property="FontSize" Value="12" />
  <Setter Property="Foreground" Value="{StaticResource MyForeground}" />
  <Setter Property="Background" Value="{StaticResource MyBackground}" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="TextBox">
        <Border Name="Bd" BorderThickness="{TemplateBinding BorderThickness}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            Background="{TemplateBinding Background}" 
            SnapsToDevicePixels="true">

            <ScrollViewer Name="PART_ContentHost" 
                Background="{TemplateBinding Background}" 
                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
        </Border>

        <ControlTemplate.Triggers>
          <Trigger Property="local:MyTextBox.IsRequired" Value="False">
            <Setter Property="Background" Value="{StaticResource RequiredBackground}" />
            <Setter TargetName="PART_ContentHost" Property="Background" 
                 Value="RequiredBackground"/>
          </Trigger>
          <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Background" Value="{StaticResource MyDisBackground}" />
            <Setter TargetName="PART_ContentHost" Property="Background" 
                 Value="MyDisBackground"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<Style TargetType="local:MyTextBox"  BasedOn="{StaticResource {x:Type TextBox}}" />

Benche 'la proprietà non esiste per TextBox, si può ancora ottenere il valore di default della vostra proprietà di dipendenza e grilletto fuori di esso. Ma dal momento che sarebbe stato impostato per un controllo TextBox, non verrà mai utilizzato quel grilletto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top