0

編集: Slider.ValueChanged イベントで長時間ロックがかかりました。これを削除すると、奇妙さが止まります。悪い習慣ですが、その動作はまだ私には意味がありません。おそらくメッセージキューが関係しているのでしょうが、できれば説明が欲しいです。

UI スレッド* に重要な作業がある場合、WPF スライダーは期待どおりにマウスと対話しません。親指を一方向にドラッグすると、親指がマウス カーソルの前に進み、その後戻ることがよくあります。移動によって ValueChanged イベントが増加するだけですが、イベントが減少することがあります。この振動は、マウス カーソルの背後でも発生することがあります。マウスの位置は、現在の速度によって予測されるようです。

この動作を変更できますか、それとも何か間違っていますか?

IsSnapToTickEnabled を切り替えても役に立ちません。

* 大きな BitmapSource を Image に割り当てる。BitmapSource はワーカー スレッドで作成されます。

<Window x:Class="WPFSliderBug.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Image Name="image1" Stretch="Fill" />
    <Slider HorizontalAlignment="Right" Name="slider1" VerticalAlignment="Stretch" Orientation="Vertical" />
</Grid>
</Window>

xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;

using System.Threading;

namespace WPFSliderBug
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private volatile bool m_run = true;
        private double m_sliderValue;

        public MainWindow()
        {
            InitializeComponent();

            this.Closing += new System.ComponentModel.CancelEventHandler(MainWindow_Closing);
            this.slider1.Minimum = 1;
            this.slider1.Maximum = 30;
            this.slider1.SmallChange = 0.5;
            this.slider1.LargeChange = 0.5;
            this.slider1.TickFrequency = 0.5;
            this.slider1.TickPlacement = System.Windows.Controls.Primitives.TickPlacement.Both;
            this.slider1.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slider1_ValueChanged);

            Thread t = new Thread((unused_state) =>
            {
                while (m_run)
                {

                    BitmapSource bmp;
                    lock (this)
                    {
                        bmp = ToBitmapSource();
                        bmp.Freeze();
                    }

                    this.Dispatcher.Invoke(new Action(delegate()
                    {
                        image1.Source = bmp;
                    }));
                }
            });

            t.Start();
        }

        void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            lock (this)
            {
                m_sliderValue = e.NewValue;
            }
        }

        void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {

                m_run = false;
        }

        public BitmapSource ToBitmapSource()
        {
            Random rng = new Random();
            double dpi = 96;
            int bytesPerPixel = 1;
            int width = 2048;
            int height = 2048;

            int stride = ((width * 32 + 31) & ~31) / 8;

            UInt32[] pixelData = new UInt32[width * height];
            for (int i = 0; i < pixelData.Length; ++i)
            {
                double r = rng.NextDouble();
                r = Math.Sin(r) * Math.Cos(r) + Math.Asin(r);
                pixelData[i] = (uint)(r * UInt32.MaxValue);
            }


            BitmapSource bmpSource = BitmapSource.Create(width, height, dpi, dpi,
                PixelFormats.Bgr32, null, pixelData, stride);

            return bmpSource;
        }
    }
}
4

0 に答える 0