e.OriginalSource返回错误信息

本文关键字:信息 错误 返回 OriginalSource | 更新日期: 2023-09-27 18:01:08

我正在制作一个自定义滑块,它是自定义控件(颜色选择器(的一部分。RGBA使用了4次滑块,当其中一个滑块发生变化时,我需要更新颜色选择器其他部分的颜色(其他自定义控件,如HueWheel等(。

ColorSlider类:

public class ColorSlider : Slider
{
    static ColorSlider()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorSlider), new FrameworkPropertyMetadata(typeof(ColorSlider)));
    }
    public Color LeftColor
    {
        get { return (Color)GetValue(LeftColorProperty); }
        set { SetValue(LeftColorProperty, value); }
    }
    public static readonly DependencyProperty LeftColorProperty =
    DependencyProperty.Register("LeftColor", typeof(Color), typeof(ColorSlider), new UIPropertyMetadata(Colors.Black));
    public Color RightColor
    {
        get { return (Color)GetValue(RightColorProperty); }
        set { SetValue(RightColorProperty, value); }
    }
    public static readonly DependencyProperty RightColorProperty =
    DependencyProperty.Register("RightColor", typeof(Color), typeof(ColorSlider), new UIPropertyMetadata(Colors.White));
    private bool _isPressed = false;
    private Slider _PART_Slider;
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        _PART_Slider = (Slider)GetTemplateChild("PART_Slider");
        _PART_Slider.ApplyTemplate();
    }
    protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        base.OnPreviewMouseLeftButtonDown(e);
        _isPressed = true;
        if (_isPressed)
        {
            Point position = e.GetPosition(_PART_Slider);
            double d = 1.0d / _PART_Slider.ActualWidth * position.X;
            var p = _PART_Slider.Maximum * d;
            _PART_Slider.Value = p;
        }
        e.Handled = true;
    }
    protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
    {
        base.OnPreviewMouseLeftButtonUp(e);
        _isPressed = false;
    }
    protected override void OnMouseMove(MouseEventArgs e)
    {
        if (_isPressed)
        {  
            Point position = e.GetPosition(_PART_Slider);
            double d = 1.0d / _PART_Slider.ActualWidth * position.X;
            var p = _PART_Slider.Maximum * d;
            _PART_Slider.Value = p;
        }
    }
}

及其XAML:

<Style TargetType="{x:Type local:ColorSlider}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ColorSlider}">
                <Border>
                    <Border.Background>
                        <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                            <GradientStop Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LeftColor}" Offset="0"/>
                            <GradientStop Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=RightColor}" Offset="1"/>
                        </LinearGradientBrush>
                    </Border.Background>
                    <Slider x:Name="PART_Slider" Maximum="255">
                        <Slider.Template>
                            <ControlTemplate>
                                <Grid x:Name="Part_Grid">
                                    <Track Grid.Row="1" Margin="-3,0,-2,0" x:Name="PART_Track" >
                                        <Track.DecreaseRepeatButton>
                                            <RepeatButton Style="{StaticResource ColorPickerRepeatButtonStyle}" 
                                                          Command="{x:Static Slider.DecreaseLarge}" />
                                        </Track.DecreaseRepeatButton>
                                        <Track.IncreaseRepeatButton>
                                            <RepeatButton Style="{StaticResource ColorPickerRepeatButtonStyle}" 
                                                          Command="{x:Static Slider.IncreaseLarge}" />
                                        </Track.IncreaseRepeatButton>
                                        <Track.Thumb>
                                            <Thumb x:Name="Part_Thumb" Style="{StaticResource ColorSliderThumbStyle}">
                                                <Thumb.RenderTransform>
                                                    <TranslateTransform Y="5"/>
                                                </Thumb.RenderTransform>
                                            </Thumb>
                                        </Track.Thumb>
                                    </Track>
                                </Grid>
                            </ControlTemplate>
                        </Slider.Template>
                    </Slider>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

在我的颜色选择器类中,如果其中一个滑块发生变化,我会尝试更新颜色:

private void OnSliderValueChanged(RoutedPropertyChangedEventArgs<double> e)
{
    // Avoid endless loop
    if (m_withinChange)
        return;
    m_withinChange = true;
    Console.WriteLine(e.OriginalSource);
    if (e.OriginalSource == m_redColorSlider ||
        e.OriginalSource == m_greenColorSlider ||
        e.OriginalSource == m_blueColorSlider ||
        e.OriginalSource == m_alphaColorSlider)
    {
        Color newColor = GetRgbColor();
        UpdateHsvControlColor(newColor);
        UpdateSelectedColor(newColor);
    }
    else if (e.OriginalSource == m_hueWheel)
    {
        double hue = m_hueWheel.Hue;
        UpdateHsvControlHue(hue);
        Color newColor = GetHsvColor();
        UpdateRgbColors(newColor);
        UpdateSelectedColor(newColor);
    }
    m_withinChange = false;
}
private static void OnSliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    ColorPicker colorPicker = (ColorPicker)sender;
    colorPicker.OnSliderValueChanged(e);
}

问题是,条件e.OriginalSource == m_redColorSlider永远不会为真,因此颜色永远不会更新。事实上,如果我执行Console.WriteLine(e.OriginalSource),控制台会显示"System.Windows.Controls.Slider",而不是类似"ColorPicker.ColorSlider"的内容。但是,我制作的另一个控件HueWheel(另一个类中的圆形滑块(在这种情况下工作正常,但找不到区别。。。

知道吗?

谢谢

编辑---

这里有一个下载这个小项目的链接:ColorPicker

由于我完全是CustomControl编程的初学者,也许我错过了对这个问题的一些解释。

e.OriginalSource返回错误信息

问题在您的Slider Control中不要在另一个Slider中嵌套Slider

XAML

<Style TargetType="{x:Type local:ColorSlider}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ColorSlider}">
                    <Border>
                        <Border.Background>
                            <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                                <GradientStop Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LeftColor}" Offset="0"/>
                                <GradientStop Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=RightColor}" Offset="1"/>
                            </LinearGradientBrush>
                        </Border.Background>
                        <Grid x:Name="Part_Grid">
                            <Track Grid.Row="1" Margin="-3,0,-2,0" x:Name="PART_Track" >
                                <Track.DecreaseRepeatButton>
                                    <RepeatButton Style="{StaticResource ColorPickerRepeatButtonStyle}" 
                                                              Command="{x:Static Slider.DecreaseLarge}" />
                                </Track.DecreaseRepeatButton>
                                <Track.IncreaseRepeatButton>
                                    <RepeatButton Style="{StaticResource ColorPickerRepeatButtonStyle}" 
                                                              Command="{x:Static Slider.IncreaseLarge}" />
                                </Track.IncreaseRepeatButton>
                                <Track.Thumb>
                                    <Thumb x:Name="Part_Thumb" Style="{StaticResource ColorSliderThumbStyle}">
                                        <Thumb.RenderTransform>
                                            <TranslateTransform Y="5"/>
                                        </Thumb.RenderTransform>
                                    </Thumb>
                                </Track.Thumb>
                            </Track>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

代码

public class ColorSlider : Slider {
        static ColorSlider() {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorSlider), new FrameworkPropertyMetadata(typeof(ColorSlider)));
        }
        #region Dependency Properties
        public Color LeftColor {
            get { return (Color) GetValue(LeftColorProperty); }
            set { SetValue(LeftColorProperty, value); }
        }
        public static readonly DependencyProperty LeftColorProperty =
        DependencyProperty.Register("LeftColor", typeof(Color), typeof(ColorSlider), new UIPropertyMetadata(Colors.Black));
        public Color RightColor {
            get { return (Color) GetValue(RightColorProperty); }
            set { SetValue(RightColorProperty, value); }
        }
        public static readonly DependencyProperty RightColorProperty =
        DependencyProperty.Register("RightColor", typeof(Color), typeof(ColorSlider), new UIPropertyMetadata(Colors.White));
        #endregion

        private bool _isPressed = false;
        protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) {
            base.OnPreviewMouseLeftButtonDown(e);
            _isPressed = true;
            if (_isPressed) {
                Point position = e.GetPosition(this);
                double d = 1.0d / this.ActualWidth * position.X;
                var p = this.Maximum * d;
                this.Value = p;
            }
            e.Handled = true;
        }
        protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e) {
            base.OnPreviewMouseLeftButtonUp(e);
            _isPressed = false;
        }
        protected override void OnMouseMove(MouseEventArgs e) {
            if (_isPressed) {
                Point position = e.GetPosition(this);
                double d = 1.0d / this.ActualWidth * position.X;
                var p = this.Maximum * d;
                this.Value = p;
            }
        }
    }

由于您已经继承了滑块,所以您不必在自己的内部放置另一个滑块。

对于许可:你的实际控制没有发射任何事件。嵌套滑块完成

干杯