.net “更改选择”;“风格”;在WPF中

.net “更改选择”;“风格”;在WPF中,.net,wpf,.net,Wpf,我有一个WPF应用程序中带有一些行的图表 当用户选择线条(鼠标)时,我需要更改其外观。 阿拉: 在WPF中,两行代码可以如下所示: <Line X1= "10" Y1="20" X2="150" Y2="20" Stroke="Black" StrokeThickness="1" /> <Line X1= "10" Y1="50" X2="150" Y2="50"

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

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

在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" />

  • 当用户选择对象(线)时,如何更改线“样式”

  • >P>是否有可能保持“箭头”在段的中间?


    有没有一个原因让你不能在代码隐藏中这样做?因此,将MouseDown事件添加到行中,然后在MouseDown事件中执行如下操作:

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

    再加上更改笔划厚度,并将箭头添加到线条的中间。类似地,您可以声明一个局部变量来保存选定的行,以便在选择另一行时,可以在先前选定的行上重置样式。这不起作用吗?

    有什么原因不能在代码隐藏中这样做吗?因此,将MouseDown事件添加到行中,然后在MouseDown事件中执行如下操作:

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

    再加上更改笔划厚度,并将箭头添加到线条的中间。类似地,您可以声明一个局部变量来保存选定的行,以便在选择另一行时,可以在先前选定的行上重置样式。这样不行吗?

    我只需要创建一个从形状继承的自定义控件(您不能从线条继承,因为它是密封的)

    新控件将有一个IsSelected属性,该属性在MouseDown上设置为true,在MouseUp上设置为false。它还具有确定箭头位置和旋转的属性

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

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


    我想您会发现这样做会使它更易于扩展、维护等。

    我只需创建一个从形状继承的自定义控件(您无法从线条继承,因为它是密封的)

    新控件将有一个IsSelected属性,该属性在MouseDown上设置为true,在MouseUp上设置为false。它还具有确定箭头位置和旋转的属性

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

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


    我想您会发现这样做会使它更易于扩展、维护等。

    您可以像下面这样定义箭头形状(将所有显示的属性替换为依赖属性。显示了一个示例)。然后,您可以添加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;
                }
            }
        }
    
    更新
    添加了一个依赖项属性示例。

    您可以按如下方式定义箭头形状(用依赖项属性替换所有显示的属性。显示了一个示例)。然后,您可以添加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;
                }
            }
        }
    
    更新
    添加了一个单独的依赖属性示例。

    因此,您可以通过代码向每个鼠标向下的通道建议线条笔划,并向画布添加一个新的多边形(根据线条坐标的依赖关系以数学方式计算其坐标)。因此,对于图表中的每一条选定线。。。大概取消选中时,查找并删除相应的多边形…因此,您通过代码向每个鼠标向下移动的通道建议线条笔划,并向画布添加一个新多边形(根据线条坐标以数学方式计算其坐标)。因此,对于图表中的每一条选定线。。。大概当取消选中时,查找并删除相应的多边形…你所说的“数组”是什么意思。你是说“箭头”吗?你说的“阵列”是什么意思。你是说“箭”吗?这个叫whell,thans。[TypeConverter(typeof(LengthConverter))]的含义是什么?它是从其他类型到X1,Y1坐标的默认类型转换器的规范。XAML使用默认类型转换器与坐标的字符串表示形式进行转换。LengthConverter是一个有点错误的名称,但这是WPF框架用于其线坐标的名称。。。依赖项属性在设计器中的行为与标准行属性不同。我的意思是,当我在XAML中更改它们时,自定义行不会在设计器中自动更新。顺便提一下,这是另一个问题:奇怪的是,FrameworkPropertyMetadataOptions.AffectsRender是在X1属性中设置的。在依赖项属性在设计器中工作之前,您可能需要重新编译。[TypeConverter(typeof(LengthConverter))]的含义是什么?它是从其他类型到X1,Y1坐标的默认类型转换器的规范。XAML使用默认类型转换器与坐标的字符串表示形式进行转换。LengthConverter是一个有点错误的名称,但这是WPF框架用于其线坐标的名称。。。依赖项属性在设计器中的行为与