Как заставить объект менять цвет с помощью MouseEnter и MouseLeave WPF

Что ж, это мой проект WPF, и проблема заключается в этом пользовательском элементе управления, файле People.xaml.cs:

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;
    }

ИТ берет данные из файла. В файле есть имена людей и их рост. Он превращает эти высоты в гистограмму, используя прямоугольники на холсте. Я хочу изменить цвет прямоугольников с помощью MouseEnter и MouseLeave, но это просто меняет цвет фона моего холста. На всякий случай я тоже оставлю здесь свой People.xaml.

<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>


person user2983594    schedule 03.12.2013    source источник
comment
Это ВПФ? WinForms? Что-то другое? Пожалуйста, отметьте свой вопрос соответствующим образом.   -  person Adi Lester    schedule 04.12.2013
comment
Есть ли конкретная причина, по которой вы не хотите использовать скрипт, такой как Java? Просто любопытно.   -  person Jfabs    schedule 04.12.2013
comment
Может помочь, если вы покажете нам часть вашего кода, которая импортирует пространства имен и определяет, с какими объектами вы работаете... Похоже на WinForms, но я понятия не имею, к какому элементу управления вы привязываете события мыши. Панель?   -  person    schedule 04.12.2013
comment
Я отредактировал вопрос и добавил дополнительную информацию   -  person user2983594    schedule 04.12.2013


Ответы (2)


Вы должны прикрепить обработчики событий к каждому прямоугольнику, а не к холсту. Удалите их здесь:

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

Затем добавьте их в каждый прямоугольник:

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;
}

Сказав это, я настоятельно рекомендую выбросить весь этот код и вместо этого использовать подход MVVM. Возможно, начните читать об ItemsControl и шаблоны данных .

person Clemens    schedule 03.12.2013

Нет абсолютно никакой причины использовать для этого код, просто используйте стиль и триггер IsMouseOver (хотя в вашем случае, очевидно, измените сеттеры, чтобы изменить/заменить соответствующие свойства дочернего элемента управления):

<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>
person Mark Feldman    schedule 03.12.2013