简体   繁体   中英

Change background color on group of objects with ismouseover

I am really new to WPF+C# and trying to catch up with lots of tutorials at msdn and here at stack. I am currently trying to change the colour of all the objects (at the same time) below (drawing of a house) on ismouseover . I can do this with one object (triggers in the code below) at a time but cant figure out some way to change all colours at the same time, here is my xaml code, i have not added anything to xaml.cs I guess that i need to create some for loop but I do not understand how to link the objects drawn in xaml to the code in xaml.cs

<Window x:Class="LAB2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="400" Width="600">
<Canvas>

    <Rectangle Canvas.Left="86" Canvas.Top="190" Height="171" Name="body" Stroke="Black" Width="387"/>
    <Rectangle Canvas.Left="118" Canvas.Top="229" Height="82"  Name="window" Stroke="Black" Width="89"/>
    <Rectangle Canvas.Left="346" Canvas.Top="229" Height="132"  Name="door" Stroke="Black" Width="83"/>
    <Polygon Points="10,110 230,10 500,110" Fill="Blue" Stroke="Black" Name="triangle" Canvas.Left="35" Canvas.Top="86" />
    <Rectangle Canvas.Left="156" Canvas.Top="109" Height="61" Name="chimney" Stroke="Black" Width="36">
        <Rectangle.Style>
            <Style TargetType="{x:Type Rectangle}">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Fill" Value="Red" />
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="False">
                        <Setter Property="Fill" Value="Blue" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Rectangle.Style>
    </Rectangle>
</Canvas>
<Window.Resources>

</Window.Resources>

You will need to move triggers higher... and because you can use triggers only within ControlTemplate or Style my solution is little tricky.

    <Control>
        <Control.Template>
            <ControlTemplate>
                <Canvas>
                    <Rectangle Canvas.Left="86" Canvas.Top="190" Height="171" Fill="Blue" Name="body" Stroke="Black" Width="387"/>
                    <Rectangle Canvas.Left="118" Canvas.Top="229" Height="82" Fill="Blue"  Name="window" Stroke="Black" Width="89"/>
                    <Rectangle Canvas.Left="346" Canvas.Top="229" Fill="Blue" Height="132"  Name="door" Stroke="Black" Width="83"/>
                    <Polygon Points="10,110 230,10 500,110" Fill="Blue" Stroke="Black" Name="triangle" Canvas.Left="35" Canvas.Top="86" />
                    <Rectangle Canvas.Left="156" Canvas.Top="109" Height="61" Fill="Blue" Name="chimney" Stroke="Black" Width="36">
                    </Rectangle>
                </Canvas>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="body" Property="Fill" Value="Red" />
                        <Setter TargetName="window" Property="Fill" Value="Red" />
                        <Setter TargetName="door" Property="Fill" Value="Red" />
                        <Setter TargetName="triangle" Property="Fill" Value="Red" />
                    </Trigger>
                    <!--<Trigger Property="IsMouseOver" Value="False">
                        <Setter TargetName="body" Property="Fill" Value="Green" />
                        <Setter TargetName="window" Property="Fill" Value="Green" />
                        <Setter TargetName="door" Property="Fill" Value="Green" />
                        <Setter TargetName="triangle" Property="Fill" Value="Green" />
                    </Trigger>-->
                </ControlTemplate.Triggers>     
            </ControlTemplate>
        </Control.Template>
    </Control>

When you don't set Background property in Canvas you get better behavior because canvas will ignore IsMouseOver and Trigger will work only when you move your cursor over one of objects within Canvas

You could remove your style triggers, and attach methods to the MouseEnter and MouseLeave events in the .xaml.cs file:

    private void body_MouseEnter(object sender, MouseEventArgs e)
    {
        foreach(var c in canvas.Children)
        {
            if(c is Shape) (c as Shape).Fill = Brushes.Red;
        }
    }

    private void body_MouseLeave(object sender, MouseEventArgs e)
    {
        foreach (var c in canvas.Children)
        {
            if (c is Shape) (c as Shape).Fill = Brushes.Blue;
        }
    }

This seems like the brute force method, but it works.

Also, You can define a base style for Shape and then derive it for Polygon and rectangle.

 <Window.Resources>
    <Style x:Key="ShapeMouseOverStyle" TargetType="{x:Type Shape}">
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Fill" Value="Red" />
            </Trigger>
            <Trigger Property="IsMouseOver" Value="False">
                <Setter Property="Fill" Value="Blue" />
            </Trigger>
        </Style.Triggers>
    </Style>
    <Style TargetType="{x:Type Rectangle}" BasedOn="{StaticResource ShapeMouseOverStyle}"/>
    <Style TargetType="{x:Type Polygon}" BasedOn="{StaticResource ShapeMouseOverStyle}"/>
</Window.Resources>

<Grid>
    <Canvas>
        <Rectangle Canvas.Left="86" Canvas.Top="190" Height="171" Name="body" Stroke="Black" Width="387"/>
        <Rectangle Canvas.Left="118" Canvas.Top="229" Height="82"  Name="window" Stroke="Black" Width="89"/>
        <Rectangle Canvas.Left="346" Canvas.Top="229" Height="132"  Name="door" Stroke="Black" Width="83"/>
        <Polygon Points="10,110 230,10 500,110" Fill="Blue" Stroke="Black" Name="triangle" Canvas.Left="35" Canvas.Top="86" />
        <Rectangle Canvas.Left="156" Canvas.Top="109" Height="61" Name="chimney" Stroke="Black" Width="36"/>
    </Canvas>

</Grid>

Cheers...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM