我正在尝试将滑块绑定到继承自shape的类的依赖项属性,但似乎只能以一种方式工作(从类到滑块)。如果我通过它后面的代码设置属性,并且滑块会更新
感谢任何想法或帮助
<Window x:Class="Controls.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Controls"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid>
<StackPanel>
<Border Width="200" Height="200">
<local:Pie x:Name="piece1" StartAngle="45" EndAngle="90"/>
</Border>
<Slider Maximum="360" Minimum="0" Value="{Binding Path=StartAngle, ElementName=piece1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></Slider>
<Button Content="Move" Width="100" HorizontalAlignment="Left" VerticalAlignment="Top" Click="Button_Click" />
</StackPanel>
</Grid>
</Grid>
</Window>
这是我要绑定的类。基本上是创建一种饼图/切片。
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace Controls
{
public class Pie : Shape
{
public static readonly DependencyProperty StartAngleProperty =
DependencyProperty.Register("StartAngle", typeof(int), typeof(Pie),
new PropertyMetadata(default(int)));
public static readonly DependencyProperty EndAngleProperty =
DependencyProperty.Register("EndAngle", typeof(int), typeof(Pie),
new PropertyMetadata(default(int)));
public int StartAngle
{
get { return (int) GetValue(StartAngleProperty); }
set
{
SetValue(StartAngleProperty, value);
InvalidateVisual();
}
}
public int EndAngle
{
get { return (int)GetValue(EndAngleProperty); }
set
{
SetValue(EndAngleProperty, value);
InvalidateVisual();
}
}
private const int CenterX = 100;
private const int CenterY = 100;
private const int Radius = 100;
private double Angle
{
get
{
if (StartAngle > EndAngle)
return (360 - StartAngle) + EndAngle;
return EndAngle - StartAngle;
//return (360 - StartAngle) + EndAngle;
}
}
public Pie()
{
Fill = (SolidColorBrush)(new BrushConverter().ConvertFrom("#4386D8"));
Stroke = Brushes.Black;
StrokeThickness = 1;
}
public static Point ComputeCartesianCoordinate(double angle, double radius)
{
// convert to radians
double angleRad = (Math.PI / 180.0) * (angle - 90);
double x = radius * Math.Cos(angleRad);
double y = radius * Math.Sin(angleRad);
return new Point(x, y);
}
protected override Geometry DefiningGeometry
{
get
{
StreamGeometry geometry = new StreamGeometry();
geometry.FillRule = FillRule.EvenOdd;
using (StreamGeometryContext context = geometry.Open())
{
DrawGeometry(context);
}
geometry.Freeze();
return geometry;
}
}
private void DrawGeometry(StreamGeometryContext context)
{
Point startPoint = new Point(CenterX, CenterY);
Point outerArcStartPoint = ComputeCartesianCoordinate(StartAngle, Radius);
outerArcStartPoint.Offset(CenterX, CenterY);
Point outerArcEndPoint = ComputeCartesianCoordinate(StartAngle + Angle, Radius);
outerArcEndPoint.Offset(CenterX, CenterY);
bool largeArc = Angle > 180.0;
Size outerArcSize = new Size(Radius, Radius);
context.BeginFigure(startPoint, true, true);
context.LineTo(outerArcStartPoint, true, true);
context.ArcTo(outerArcEndPoint, outerArcSize, 0, largeArc, SweepDirection.Clockwise, true, true);
}
}
}
答案 0 :(得分:1)
实际上 都正确地以两种方式更改了值,您会用Debug.Print
注意到它。仅,执行Binding
时,框架不一定会调用属性的setter。代码中的问题是,您正在InvalidateVisual()
属性的设置器中执行StartAngle
,但是正如MSDN指出的here:
在所有例外情况下,包装器实现 应该分别仅执行GetValue和SetValue操作。 原因在主题XAML加载和 依赖项属性。
您应该改为声明DependencyProperty
,以便使用FrameworkPropertyMetadata
对象在更新时自动使视觉无效:
public static readonly DependencyProperty StartAngleProperty = DependencyProperty.Register(
"StartAngle",
typeof(int),
typeof(Pie),
new FrameworkPropertyMetadata(default(int), FrameworkPropertyMetadataOptions.AffectsRender)
);
然后像这样离开您的吸气器/吸气器:
public int StartAngle {
get { return (int)GetValue(StartAngleProperty); }
set { SetValue(StartAngleProperty, value); }
}
现在,您将在移动滑块时看到控件的重绘。