【发布时间】:2019-09-09 16:15:10
【问题描述】:
您好,当父控件 DockPanel 将其可见性设置为折叠时,我制作了这个未正确绑定的 XYController。隐藏时它工作正常。
ThumbPosX 和 ThumbPosY 应该移动,因为属性 Sat 和 Val 是从不同的地方控制的。但是当它回到 Visible 时,它们总是回到 [0, 0]。
public class XYController : Control
{
static XYController()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(XYController), new FrameworkPropertyMetadata(typeof(XYController)));
EventManager.RegisterClassHandler(typeof(XYController), Thumb.DragDeltaEvent, new DragDeltaEventHandler(XYController.OnThumbDragDelta));
}
#region Private Members
private const string ThumbName = "PART_Thumb";
private TranslateTransform m_thumbTransform = new TranslateTransform();
private Thumb m_thumb;
#endregion
#region Dependency Properties
public Color SelectedColor
{
get { return (Color)GetValue(SelectedColorProperty); }
set { SetValue(SelectedColorProperty, value); }
}
public static readonly DependencyProperty SelectedColorProperty =
DependencyProperty.Register("SelectedColor", typeof(Color), typeof(XYController),
new PropertyMetadata(Colors.Transparent));
public double ThumbPosX
{
get { return (double)GetValue(ThumbPosXProperty); }
set { SetValue(ThumbPosXProperty, value); }
}
public static readonly DependencyProperty ThumbPosXProperty =
DependencyProperty.Register("ThumbPosX", typeof(double), typeof(XYController),
new PropertyMetadata(0.0, new PropertyChangedCallback(OnThumbPosChanged)));
public double ThumbPosY
{
get { return (double)GetValue(ThumbPosYProperty); }
set { SetValue(ThumbPosYProperty, value); }
}
public static readonly DependencyProperty ThumbPosYProperty =
DependencyProperty.Register("ThumbPosY", typeof(double), typeof(XYController),
new PropertyMetadata(0.0, new PropertyChangedCallback(OnThumbPosChanged)));
private static void OnThumbPosChanged(DependencyObject relatedObject, DependencyPropertyChangedEventArgs e)
{
XYController xycontroller = relatedObject as XYController;
if (xycontroller != null)
{
xycontroller.m_thumbTransform.X = xycontroller.ThumbPosX * xycontroller.ActualWidth;
xycontroller.m_thumbTransform.Y = xycontroller.ThumbPosY * xycontroller.ActualHeight;
}
}
#endregion
private void UpdatePosition(double positionX, double positionY)
{
positionX = LimitValue(positionX, ActualWidth);
positionY = LimitValue(positionY, ActualHeight);
m_thumbTransform.X = positionX;
m_thumbTransform.Y = positionY;
ThumbPosX = map(positionX, 0, ActualWidth, 0, 1);
ThumbPosY = map(positionY, 0, ActualHeight, 0, 1);
}
#region Event Handlers
private void OnThumbDragDelta(DragDeltaEventArgs e)
{
double offsetX = m_thumbTransform.X + e.HorizontalChange;
double offsetY = m_thumbTransform.Y + e.VerticalChange;
UpdatePosition(offsetX, offsetY);
}
private static void OnThumbDragDelta(object sender, DragDeltaEventArgs e)
{
XYController hsvControl = sender as XYController;
hsvControl.OnThumbDragDelta(e);
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
if (m_thumb != null)
{
Point position = e.GetPosition(this);
UpdatePosition(position.X, ActualHeight - position.Y); //Check canvas scale in style
m_thumb.RaiseEvent(e);
}
base.OnMouseLeftButtonDown(e);
}
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
m_thumbTransform.X = ThumbPosX * ActualWidth;
m_thumbTransform.Y = ThumbPosY * ActualHeight;
base.OnRenderSizeChanged(sizeInfo);
}
#endregion
private double LimitValue(double value, double max)
{
if (value < 0)
value = 0;
if (value > max)
value = max;
return value;
}
private double map(double value, double fromLow, double fromHigh, double toLow, double toHigh)
{
return (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
m_thumb = GetTemplateChild(ThumbName) as Thumb;
if (m_thumb != null)
{
UpdatePosition(this.ThumbPosX, this.ThumbPosY);
m_thumb.RenderTransform = m_thumbTransform;
}
}
}
所以我发布了整个内容,因为我不知道缺少什么。我还制作了自定义滑块,它们在折叠时可以正常工作。
我是这样用的:
<DockPanel
Visibility="{Binding Path=IsChecked, ElementName=HueRadio, Converter={StaticResource BoolToVisibility}}">
<local:ColorSlider
Minimum="0"
Maximum="360"
Orientation="Vertical"
Style="{DynamicResource HueSliderVertical}"
Value="{Binding Hue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0, 4, 16, 4"
/>
<local:XYController
x:Name="HueColorControl"
Style="{StaticResource HueController}"
SelectedColor="{Binding SelectedColor}"
ThumbPosX="{Binding Sat, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ThumbPosY="{Binding Val, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0, 4"
Height="200"
/>
</DockPanel>
只是对RadioButton 的简单绑定。如前所述,即使DockPanel 折叠,也是CustomControl 的ColorSlider 仍在移动。
我尝试将可见性直接设置为 XYController 而不是 DockPanel,但问题仍然存在。
这里有什么遗漏吗?
谢谢
【问题讨论】: