2016-08-07 8 views
1

Ich mache einen benutzerdefinierten Schieberegler, Teil eines benutzerdefinierten Steuerelements (ein Colorpicker). Der Schieberegler wird 4 Mal für RGBA verwendet, wenn einer der Schieberegler wechselt, muss ich die Farben in einem anderen Teil des Colorpickers aktualisieren (andere benutzerdefinierte Steuerung wie HueWheel, etc.).e.OriginalSource gibt falsche Informationen zurück

Die ColorSlider Klasse:

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

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

Inside my Colorpicker-Klasse Ich versuche Farben zu aktualisieren, wenn einer der Schieber geändert:

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

Problem Ist die Bedingung e.OriginalSource == m_redColorSlider nie wahr, so wird die Farbe nie aktualisiert. Tatsächlich, wenn ich eine Console.WriteLine(e.OriginalSource) mache, zeigt die Konsole "System.Windows.Controls.Slider" statt etwas wie "ColorPicker.ColorSlider". Aber ein anderes Steuerelement namens HueWheel (ein kreisförmiger Schieberegler, in einer anderen Klasse) funktioniert in diesem Fall korrekt, aber kann den Unterschied nicht finden ...

Eine Idee?

Danke

EDIT ---

Hier ist ein Link dieses kleine Projekt zum Download: ColorPicker

Als ich einen totalen Anfänger in Custom Programmierung bin, vielleicht einige ich fehle Erklärung für dieses Problem.

+0

Arent fehlt Sie den Absender auf 'OnSliderValueChanged'? Der Absender könnte die Quelle des Ereignisses anzeigen – lokusking

+0

Ich denke nicht, weil es uns für das HueWheel arbeitet, das ein anderer Teil des benutzerdefinierten Steuerelements ist. – lecloneur

Antwort

2

Das Problem liegt in Ihrer Slider-Control. Dont Nest ein Slider in einem anderen 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> 

-Code

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

Da Sie bereits von Schieber erben, müssen Sie nicht einen anderen Schieber in sich selbst setzen müssen .

Für die Freigabe: Sie tatsächliche Kontrolle feuerte kein Ereignis. Die verschachtelte Schieber hat

Prost