在WPF中更改选择“样式”

时间:2010-09-21 16:58:28

标签: .net wpf

我有一个WPF应用程序中有一些行的图表。

当用户选择(鼠标)线时,我需要更改其外观。 àla:

alt text

在WPF中,两行代码可以如下:

        <Line
            X1= "10" Y1="20" X2="150" Y2="20"
            Stroke="Black" StrokeThickness="1" />

        <Line
            X1= "10" Y1="50" X2="150" Y2="50"
            Stroke="Blue" StrokeThickness="3" />  
        <Polygon 
            Points="80,45 80,55 90,50" 
            Stroke="Blue" Fill="Blue" />
  1. 如何在用户选择对象(Line)时更改“样式”行?

  2. 是否可以将“箭头”保持在细分中间?

3 个答案:

答案 0 :(得分:3)

您可以像下面一样定义箭头形状(用依赖属性替换所有显示的属性。显示一个示例。)。然后,您可以添加IsSelected属性,并使用监视该属性的DataTrigger设置选择样式。您甚至可以为所选箭头设置动画。

   public class Arrow : Shape
    {

        public static readonly DependencyProperty X1Property = DependencyProperty.Register("X1", typeof(double), typeof(Arrow), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));

        [TypeConverter(typeof(LengthConverter))]
        public double X1
        {
        get { return (double)base.GetValue(X1Property); }
        set { base.SetValue(X1Property, value); }
        }

        // TODO: Replace with dependency properties
        [TypeConverter(typeof(LengthConverter))]
        public double X2 { get; set; }

        [TypeConverter(typeof(LengthConverter))]
        public double Y1 { get; set; }

        [TypeConverter(typeof(LengthConverter))]
        public double Y2 { get; set; }

        [TypeConverter(typeof(LengthConverter))]
        public double ArrowWidth { get; set; }

        [TypeConverter(typeof(LengthConverter))]
        public double ArrowLength { get; set; }



        protected override Geometry DefiningGeometry
        {
            get 
            { 
                var geometryGroup = new GeometryGroup();

                // Add arrow head
                var midPoint = new Point((X1 + X2) / 2.0, (Y1 + Y2) / 2.0);
                double dX = (X2 - X1);
                double dY = (Y2 - Y1);
                double length = Math.Sqrt(dX*dX + dY*dY);
                dX /= length;
                dY /= length;
                var myPathSegmentCollection = new PathSegmentCollection 
                    {
                        new LineSegment {Point = new Point(midPoint.X - dX * ArrowLength + dY * ArrowWidth/2.0, midPoint.Y - dY * ArrowLength - dX * ArrowWidth/2.0)},
                        new LineSegment {Point = new Point(midPoint.X - dX * ArrowLength - dY * ArrowWidth/2.0, midPoint.Y - dY * ArrowLength + dX * ArrowWidth/2.0)},
                        new LineSegment {Point = midPoint},
                    };
                var myPathFigure = new PathFigure {StartPoint = midPoint, Segments = myPathSegmentCollection};

                var myPathFigureCollection = new PathFigureCollection {myPathFigure};

                var myPathGeometry = new PathGeometry {Figures = myPathFigureCollection};
                geometryGroup.Children.Add(myPathGeometry);
                // Add line
                geometryGroup.Children.Add(new LineGeometry(new Point(X1, Y1), new Point(X2, Y2)));
                return geometryGroup;
            }
        }
    }

<强>更新 添加了一个示例依赖项属性。

答案 1 :(得分:2)

我只是创建一个继承自Shape的自定义控件(你不能继承Line,因为它是密封的)。

新控件的IsSelected属性设置为true OnMouseDown和false OnMouseUp。它还具有确定箭头的放置和旋转的属性。

然后,在泛型样式的ControlTemplate中,只需要一个DataTrigger,当属性IsSelected设置为True时,它指定Stroke和StrokeThickness。当然,这些也可以是可以使用TemplateBinding设置的新类(SelectedStroke和SelectedStrokeThickness)的属性。

此外,箭头始终是ControlTemplate的一部分,Visibility设置为Collapsed。在IsSelected DataTrigger中,可见性将设置为Visible。

我认为你会发现这样做会使它更具可扩展性,更易于维护等。

答案 2 :(得分:0)

为什么你不能在代码背后执行此操作?所以在该行中添加一个MouseDown事件,然后在MouseDown事件中执行类似的操作:

private void Line_MouseDown( object sender, MouseButtonEventArgs e )
{
    ( (Line)sender ).Stroke = Brushes.Blue;
}

另外更改笔划粗细并将箭头添加到线条的中间。类似地,您可以声明一个局部变量来保持选定的行,这样当选择另一行时,您可以重置之前选择的样式。那不行吗?