Как мне успокоить этого гипер-слушателя событий - PullRequest
2 голосов
/ 01 марта 2010

У меня есть простой набор инструментов Silverlight Chart и стандартный Slider в том же элементе управления. Я хочу, чтобы диаграмма обновлялась при изменении значения ползунка. Это должно быть просто. Я попытался привязать событие .ValueChanged на слайдере, но, похоже, оно срабатывает слишком часто (например, несколько раз, пока слайдер все еще находится в движении). Меня интересует только значение слайдера, когда он остановился. Производительность ужасна, если я обновляюсь так часто, как событие запускается. Поэтому я добавил пару обработчиков к событиям .MouseLeftButtonUp и .MouseLeftButtonDown, которые должны блокировать или разблокировать логику обновления диаграммы. К сожалению, .MouseLeftButtonDown не срабатывает (точки останова в обработчике не получают удар). Таким образом, этот маршрут также не является стартовым.

Я совершенно новичок в Silverlight, поэтому я ищу конструктивную критику подхода и возможные решения. Ура!

MainPage.xaml.cs:

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.DataVisualization.Charting;
using System.Windows.Input;

namespace ControlledModelView.Media
{
    public partial class MainPage : UserControl
    {
        readonly Dictionary<KeyValuePair<int, int>, Dictionary<string, double>> data = new Dictionary<KeyValuePair<int, int>, Dictionary<string, double>>();
        readonly Chart chart = new Chart { VerticalAlignment = VerticalAlignment.Top };
        private static bool sliderInMotion = true;
        public MainPage()
        {
            InitializeComponent();
            var rng = new Random();
            for (var i = 0; i < 4; i++)
                for (var d = -1; d >= -31; d--)
                    data.Add(new KeyValuePair<int, int>(i, d), GetRandomData(rng));

            var slider = new Slider { LargeChange = 7, SmallChange = 1, Minimum = -31, Maximum = -1, Value = -1, VerticalAlignment = VerticalAlignment.Bottom };
            slider.ValueChanged += SliderValueChanged;
            slider.MouseLeftButtonUp += SliderRelease;
            slider.MouseLeftButtonDown += SliderLock;
            DrawLineChart(-1);
            LayoutRoot.Children.Add(chart);
            LayoutRoot.Children.Add(slider);
        }

        static void SliderLock(object sender, MouseButtonEventArgs e)
        {
            sliderInMotion = true;
        }

        static void SliderRelease(object sender, MouseButtonEventArgs e)
        {
            sliderInMotion = false;
        }

        void SliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if(!sliderInMotion)
                DrawLineChart((int)e.NewValue);
        }

        private void DrawLineChart(int day)
        {
            chart.Series.Clear();
            for (var seriesIndex = 0; seriesIndex < 4; seriesIndex++)
            {
                chart.Series.Add(new LineSeries
                {
                    ItemsSource = data[new KeyValuePair<int, int>(seriesIndex, day)],
                    DependentValuePath = "Value",
                    IndependentValuePath = "Key",
                    AnimationSequence = AnimationSequence.Simultaneous,
                    Name = "Line" + seriesIndex,
                    Title = "Line" + seriesIndex,
                    IsSelectionEnabled = false,
                    Visibility = Visibility.Visible,
                    IsEnabled = true
                });
            }
        }

        static Dictionary<string, double> GetRandomData(Random rng)
        {
            var data = new Dictionary<string, double>();
            for (var year = 1995; year < DateTime.Now.Year; year ++)
                data.Add(year.ToString(), 500000 * rng.NextDouble());
            return data;
        }
    }
}

MainPage.xaml:

<UserControl x:Class="ControlledModelView.Media.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
    <Grid x:Name="LayoutRoot" />
</UserControl>

Ответы [ 2 ]

2 голосов
/ 01 марта 2010

Это, кажется, главный пример для инфраструктуры RX (IObservable), если вы можете использовать ее В одном из стандартных примеров перечислены события фильтрации по координатам (для событий MouseClick в интересующей области). Вы можете использовать это точно для вашего образца.

См. этот вопрос для некоторых деталей. Получите это здесь .

1 голос
/ 01 марта 2010

граната,

Я не разработчик Silverlight, и хотя могут быть лучшие способы сделать то, что вы пытаетесь, это выглядит вполне приемлемым решением (если оно сработало). Совершенно ясно и очевидно, что он пытается сделать.

Видя, что это не работает, моя немедленная реакция заключается в том, чтобы выяснить, является ли их событие LostFocus, которое могло бы работать вместо этого, хотя это не совсем приводит вас туда, куда вы хотите, поскольку им затем приходится отменить выбор элемента управления. , Однако этот мыслительный процесс заставляет меня задуматься, может ли другой элемент управления работать лучше? например цифра вверх, где пользователь может ввести желаемое число напрямую, большинство из них вряд ли будут продолжать нажимать вверх, поэтому вы будете получать меньше обновлений.

Но это весь путь "если не можешь решить проблему, поменяй проблему" ... Сорта.

...