How to make an object to change color with MouseEnter and MouseLeave WPF

2.3k views Asked by At

Well this is my WPF project and the problem is in this user control, People.xaml.cs file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;

namespace Projet
{
public partial class People : UserControl
{
    Random rnd = new Random();
    string filename = "C:\\Users\\Kristen\\peoples.txt";
    public People()
    {
        InitializeComponent();
        dataFromFile();
    }

 void dataFromFile()
    {
        if (!File.Exists(filename))
            return;

        var source = File.ReadLines(filename)
                         .Select(line => line.Split(' '))
                         .Select(m => new { name = m[0], length = int.Parse(m[1]) })
                         .OrderBy(x => x.length);
        int k = 200;
        foreach (var data in source)
        {

            Rectangle r = new Rectangle ();
            r.Height = data.length;
            r.Width = 25;
            r.Fill = new SolidColorBrush(Colors.Red);
            Canvas.SetLeft(r, k);
            Canvas.SetBottom(r, 200);
            board.Children.Add(r);
            k += 50;
        }
    }
    private void board_MouseEnter_1(object sender, MouseEventArgs e)
    {
        board.Background = Brushes.Blue; 
//I have tried with r.Fill = new SolidColorBrush(Colors.Red); but it wont work either
        dataFromFile();
    }

    private void juur_MouseLeave_1(object sender, MouseEventArgs e)
    {
        board.Background = Brushes.Yellow;
    }

IT takes data out of file. In file there are people names and their heights. It makes those heights to bar chart using rectangles on canvas. I want to make the color of rectangles change with MouseEnter and MouseLeave but it just changes my canvas background color. I'll but my People.xaml here too just in case.

<UserControl x:Class="Project.People"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Canvas Background="Yellow" x:Name="board" MouseEnter="board_MouseEnter_1" MouseLeave="board_MouseLeave_1">


</Canvas>

2

There are 2 answers

0
Clemens On BEST ANSWER

You have to attach the event handlers to each Rectangle, not to the Canvas. Remove them here:

<Canvas Background="Yellow" x:Name="board"/>

Then add them to each Rectangle:

foreach (var data in source)
{
    var r = new Rectangle();
    r.MouseEnter += Rectangle_MouseEnter;
    r.MouseLeave += Rectangle_MouseLeave;
    ...
}

...

private void Rectangle_MouseEnter(object sender, MouseEventArgs e)
{
    ((Rectangle)sender).Fill = Brushes.Blue; 
}

private void Rectangle_MouseLeave(object sender, MouseEventArgs e)
{
    ((Rectangle)sender).Fill = Brushes.Yellow;
}

Having said that I'd strongly suggest to throw away all that code and use an MVVM approach instead. Perhaps start reading about ItemsControl and Data Templating.

0
Mark Feldman On

There is absolutely no reason to use behind-code for this, just use a style and the IsMouseOver trigger (although in yoru case obviously change the setters to modify/replace the appropriate child control properties):

<Canvas>
    <Canvas.Style>
        <Style>
            <Setter Property="Canvas.Background" Value="Yellow"/>
            <Style.Triggers>
                <Trigger Property="Canvas.IsMouseOver" Value="True">
                    <Setter Property="Canvas.Background" Value="Red" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Canvas.Style>
</Canvas>