Member 12086889 Ответов: 0

E. originalsource возвращает неверную информацию


Я делаю пользовательский слайдер, часть пользовательского элемента управления (colorpicker). Слайдер используется 4 раза для RGBA, когда один из слайдеров меняется, мне нужно обновить цвета в другой части colorpicker (другой customcontrol, такой как 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>


Внутри моего класса colorpicker я пытаюсь обновить цвета, если один из ползунков изменился :

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


И его 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>


Внутри моего класса colorpicker я пытаюсь обновить цвета, если один из ползунков изменился :

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 никогда не истинно, поэтому цвет никогда не обновляется. Действительно, если я сделаю консоль.Метода WriteLine(электронная.OriginalSource) в консоли появляется система".Окна.Управления.Слайдер " вместо чего-то вроде "ColorPicker.ColorSlider". Но другой элемент управления, который я сделал, называется HueWheel (круговой слайдер в другом классе), работает правильно в этом случае, но не может найти разницу...

Вот ссылка для загрузки этого маленького проекта : ColorPicker

Поскольку я полный новичок в программировании CustomControl, возможно, мне не хватает какого-то объяснения этой проблемы.

Есть идеи ?

Спасибо

Что я уже пробовал:

спрашивал где-то еще, но без ответа. Как новичку, это трудно выяснить.

Richard Deeming

Вы дважды опубликовали код для класса выбора цвета и XAML для ползунка цвета. Но вы не опубликовали XAML для выбора цвета, поэтому мы не видим, как вы подключаете обработчик событий.

0 Ответов