[WPF] Trigger IsMouseOver ContentControl Child verändern
-
Ich komme irgendwie gerade nicht weiter. Ich habe ein
ContentControl
, welches einControlTemplate
bekommt. Im Template sind verschiedene Children definiert unteranderem ein<ContentPresenter Content="{TemplateBinding ContentControl.Content}" />
. Dies ist dann wiederrum eine einfache Linie (<Line>
). Jetzt möchte ich gerne, dass wenn die Maus über demContentControl
ist, die Linie in einer anderen Farbe erscheint. Wie krieg ich das sinnvoll gedreht?Grüssli
-
Zeig mal bitte dein XAML. Die ÜBerlegung das mit einem Trigger zu machen ist gut.
Aber so ohne XAML is schwer zu sagen
-
Also die Farbe der Linie beeinflusst du direkt im Template durch n Trigger
z.B.:
<ControlTemplate ...> <Grid> <Line x:Name="PART_Line" Brush="Red" ... /> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="PART_Line" Property="Brush" Value="Pink" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate>
Wenn die Linie aber nicht im ControlTemplate deines Controls liegt, benötigt diese einen eigenen Style
z.B.:
<Style> <Setter Property="Brush" Value="Red" /> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Brush" Value="Pink" /> </Trigger> </Style.Triggers> </Style>
-
@CSL,
Danke, ist aber leider nicht ganz, was ich möchte. Also, hier etwas XAML Code:<Windows.Resources> <Style x:Key="ContentControlStyle" TargetType="ContentControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Grid> <!-- bla bla bla --> <ContentPresenter Content="{TemplateBinding ContentControl.Content}"> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </Windows.Resources> <DockPanel LastChildFill="False"> <ContentControl DockPanel.Dock="Top" Height="3" UseLayoutRounding="True" Style="{StaticResource ContentControlStyle}"> <Line X1="0" Y1="1" X2="1" Y2="1" Stretch="Fill" Stroke="White" StrokeThickness="1" /> </ContentControl> </DockPanel>
Ich möchte hier nun einen
IsMouseOver
Trigger einbauen, damit wennIsMouseOver
vomContentControl
true
ist, dasDependencyProperty
Stroke
vonLine
imContentControl
aufYellow
wechselt.Grüssli
-
Hmm - komisches Konstrukt ^^
Idee:
Im ControlTemplate im Trigger das Foreground des ContentControl auf Yellow stellen, und in der Line dann Stroke gegen des Foreground Binden.
-
CSL schrieb:
Hmm - komisches Konstrukt ^^
Tz, du unterschätzt meine künstlerische Ader! :p
Ich habe es nun gelöst. Allerdings unteranderem dadurch, weil mir aufgefallen ist, dass man das Konstrukt vereinfachen kann
Schlussendlich ist es nun darauf rausgelaufen, dass
Line
Teil einesControlTemplate
von einem Custom Control ist. Daher kann ichStroke
anForeground
binden, was auch Sinn macht. Einziges Problem war noch, dassIsMouseOver
nur dann ausgelöst wurde, wenn die Maus über der Linie war, obwohl das Custom Control grösser war. Allerdings konnte ich das mit einemRectangle
mitFill
aufTransparent
lösen. Und über diese Rectangle wird dann die Linie gezeichnet.Oder wollt ihr wieder etwas XAML? *seufz*
<Canvas> <Canvas.Resources> <Style x:Key="LineThumbStyle" TargetType="{x:Type test:MoveThumb}"> <Setter Property="Cursor" Value="SizeAll" /> <Setter Property="Foreground" Value="White" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Grid> <Rectangle Fill="Transparent" /> <Line X1="0" Y1="1" X2="1" Y2="1" Stretch="Fill" Stroke="{TemplateBinding Thumb.Foreground}" StrokeThickness="1" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Foreground" Value="Yellow" /> </Trigger> </Style.Triggers> </Style> <Canvas.Resources> <test:MoveThumb Canvas.Top="50" Canvas.Left="300" Width="100" Height="3" UseLayoutRounding="True" Style="{StaticResource LineThumbStyle}" DataContext="{Binding RelativeSource={RelativeSource Self}}"/> </Canvas>
Dann kann ich nun endlich diese kleine Fallstudie abschliessen und die gewonnen Erkenntnisse ins Hauptprojekt übertragen
Danke für eure Hilfe.
Grüssli
-
Das Rectangle brauchst du nicht, du hast das mit dem Transparent richtig erkannt, so macht man das, aber du hast da schon ein Grid, setz doch einfach den Background des Grids auf Transparent, dann kannst du das Rectangle weg schmeißen.
Aber so richtig gefällt mir es nicht, wenn du die Linie im Template hast, dann Sprich "Im Control Template"! Trigger direkt die Linie an und setz die Farbe.
TextBlocks usw erben gerne mal die Foreground.<Style x:Key="LineThumbStyle" TargetType="{x:Type test:MoveThumb}"> <Setter Property="Cursor" Value="SizeAll" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type test:MoveThumb}"> <Grid Background="Transparent"> <Line x:Name="PART_Line" X1="0" Y1="1" X2="1" Y2="1" Stretch="Fill" Stroke="White" StrokeThickness="1" /> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="PART_Line" Property="Stroke" Value="Yellow" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
So lässt du dein Foreground unangetastet und hast keine bösen Side-effects, kürzer ist es zudem.
-
Finde ich aber nicht wirklich gut. So kann ich nicht die Farbe der Linie ändern. Mit meiner Lösung kann ich einfach
Foreground
eine andere Farbe zuweisen. Zusätzlich werde ich dann inMoveThumb
einHighlightColor
DependencyProperty
einführen. Ich wüsste nicht, wieForeground
irgendetwas anderes beeinflussen sollte in diesemControlTemplate
. DasControlTemplate
bestimmt schliesslich das Aussehen und wie man sieht, hat es keinenTextBlock
. Da kann keinTextBlock
vorkommen. Und wenn auch einTextBlock
vorkommen würde, dann wäre es nicht verkehrt, wenn die Schrift darin die gleiche Farbe hat wie die Linie.Grüssli
-
Oka, im diesem Fall hast du recht.
Ich nahm an das Beispiel war nur gekürzt und da ist noch mehr in dem Control außer eine Linie.