Laden...

Trigger funktionieren nicht schön

Erstellt von DiscMaster vor 11 Jahren Letzter Beitrag vor 11 Jahren 1.445 Views
DiscMaster Themenstarter:in
316 Beiträge seit 2006
vor 11 Jahren
Trigger funktionieren nicht schön

Liebe Community,

lang lang ist's her....

Ich versuch mir gerade ein UserControl basierend auf einem Button zu gestalten. Das Problem hatte ich schon öfter und hab früher oder später immer davor kapituliert. Allerdings ist es mal wieder Zeit für etwas Kampfgeist. Wie auch immer, das Problem ist das gleiche wie hier schon beschrieben. Allerdings hab ich halt kein Label sondern eben einen ContentPresenter. Das Template sieht dann ungefähr so aus (ich habe die Brushes und BorderThickness der Übersichtlichkeithalber rausgenommen):

<Border x:Name="border1">
	<ContentPresenter x:Name="contentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" IsHitTestVisible="False"/>
</Border>

Das lustige ist, ich habe fast die gleiche Konstruktion noch als Button-ControlTemplate - da taucht das Problem nicht auf.

Wenn ich jetzt dem eigenen UserControl die Eigenschaft Content="Hello World!" gebe, dann kann ich mit der Maus auf den Button "fahren" und dann greift der IsMouseOver-Trigger zunächst wie er soll. Wenn ich aber auf einem Pixel komme, der dem ContentPresenter "gehört", dann gilt für das UserControl.IsMouseOver=false.

Wie gesagt ein "normales" Button-ControlTemplate zeigt dieses Verhalten nicht. Um die Worte meines Vorredners (siehe obigen Link) zu benutzen, der ContentPresenter ist nicht "durchlässig". Allerdings behebt IsHitTestVisible="false" das Problem nicht.

Danke für jede Hilfe, das ist allmählich wirklich frustrierend.

"Flache Hierarchien schaffen! Das muss konkret nicht unbedingt etwas bedeuten, kommt aber immer sehr gut an."
Bernd Stromberg

5.657 Beiträge seit 2006
vor 11 Jahren

Hi DiscMaster,

wenn du die Mouse-Ereignisse abfangen willst, solltest du IsHitTestVisible auf true stellen.

Christian

Weeks of programming can save you hours of planning

DiscMaster Themenstarter:in
316 Beiträge seit 2006
vor 11 Jahren

Grad andersrum will ich das aber:

<ControlTemplate>
    <Border ...>
        <ContentPresenter .... />
    </Border>
</ControlTemplate>

Im Template soll jetz der trigger für IsMouseOver=true anspringen - das geh auch, solange ich explizit auf dem Border bin mit dem Cursor, komm ich aber auf den Text im ContentPresenter dann greift der trigger nicht.

Das bedeutet im Endeffekt, wenn ich mit der Maus den Button quer durchfahre, dann flimmert er (IsMouseOver ändert die Hintergrundfarbe des Borders).

Und jetzt hab ich eben gelesen, dass mit IsHitTestVisible=false für den ContentPresenter das Problem umgangen werden soll - aber das passiert eben nicht. Auch wenn ich statt des ContentPresenters andere Controls einsetze, geht das nicht...

Ich wundere mich, ob ich der einzige bin, der das Problem so hat...

"Flache Hierarchien schaffen! Das muss konkret nicht unbedingt etwas bedeuten, kommt aber immer sehr gut an."
Bernd Stromberg

5.742 Beiträge seit 2007
vor 11 Jahren

Wenn ich aber auf einem Pixel komme, der dem ContentPresenter "gehört", dann gilt für das UserControl.IsMouseOver=false.

Eigentlich gerade nicht; bei IsMouseDirectlyOver ist dies höchstens der Fall (sicher, dass du nicht gegen das gebunden hast?).

Kleines Beispiel, das bei mir funktioniert, wie es soll:

<Button Content="Foo">
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Border x:Name="_border" Margin="20" BorderThickness="10" BorderBrush="Black">
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" TextBlock.FontSize="90" />
            </Border>
                    
            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="Red" TargetName="_border" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Button.Template>
</Button>
DiscMaster Themenstarter:in
316 Beiträge seit 2006
vor 11 Jahren

Ja, das ist ja gerade das was mich so an den Wahnsinn treibt! Wenn ich ein Button-ControlTemplate erstelle, dann hab ich das Problem nicht - wenn ich allerdings eine Klasse von Button ableite, und dafür das Template erstelle, dann taucht besagtes Problem auf.

"Flache Hierarchien schaffen! Das muss konkret nicht unbedingt etwas bedeuten, kommt aber immer sehr gut an."
Bernd Stromberg

5.742 Beiträge seit 2007
vor 11 Jahren

wenn ich allerdings eine Klasse von Button ableite, und dafür das Template erstelle, dann taucht besagtes Problem auf.

Dann leite einfach keine Klasse von Button ab 😁

Klappt es denn bei Ableitung von ButtonBase oder CustomControl?

Poste am besten mal ein kleines (aber vollständiges) Mini-Beispiel.

DiscMaster Themenstarter:in
316 Beiträge seit 2006
vor 11 Jahren

Ich werd bekloppt...

Gibt kein Beispiel - denn ich habe eins erstellt, das hat das Problem nicht mehr. Dann habe ich den Quelltext von meinem Problemkind reinkopiert - jetzt hab ich das Control ohne Fehlverhalten... ist das zu fassen?

Dann werd ich mich jetzt mal auf die Suche nach dem kleinen aber feinen Unterschied machen - irgendwo muss ne kleine Codezeile fehlen, die des Bösen Ursprungs ist.

Ich meld mich wenn ich was finde.

"Flache Hierarchien schaffen! Das muss konkret nicht unbedingt etwas bedeuten, kommt aber immer sehr gut an."
Bernd Stromberg

DiscMaster Themenstarter:in
316 Beiträge seit 2006
vor 11 Jahren

Bingo!

Das Problem ist nicht der ContentPresenter oder sonst ein Control - sondern der Ort wo ich es platziert habe. Nämlich im Header einer GroupBox.

So ganz interpretieren kann ich das zwar noch nicht, aber es sieht ganz danach aus, als würde der Border der GroupBox den HitTest abgreifen - versteh zwar nicht wieso, denn der müsste ja eigentlich darunter liegen. Aber was solls.

Danke für eure Unterstützung!

"Flache Hierarchien schaffen! Das muss konkret nicht unbedingt etwas bedeuten, kommt aber immer sehr gut an."
Bernd Stromberg