原文:
绑定元素属性改变不通知界面
情景假设:绑定的是一个Point,当Point的X或者Y属性发生改变时,绑定的点也随界面改变
此时界面不会发生改变
原因:当X或者Y属性发生改变时并没有触发Point的Set方法
1 <Grid> 2 <Grid.Resources> 3 <local:PConverter x:Key="converter"/> 4 <local:PointsConverter x:Key="pointsC"/> 5 6 <Style TargetType="Ellipse"> 7 <Setter Property="Height" Value="5"/> 8 <Setter Property="Width" Value="5"/> 9 <Setter Property="HorizontalAlignment" Value="Left"/> 10 <Setter Property="VerticalAlignment" Value="Top"/> 11 </Style> 12 </Grid.Resources> 13 14 15 <Grid.ColumnDefinitions> 16 <ColumnDefinition/> 17 <ColumnDefinition/> 18 </Grid.ColumnDefinitions> 19 20 21 <Grid x:Name="PathGrid" Grid.Column="0"> 22 <Border BorderBrush="AliceBlue" BorderThickness="5"/> 23 24 <Path Stroke="BlueViolet" StrokeThickness="3"> 25 <Path.Data> 26 <PathGeometry> 27 <PathFigure StartPoint="{Binding ElementName=OwnerWindow,Path=StartPoint}"> 28 <PathFigure.Segments> 29 <PolyBezierSegment 30 IsSmoothJoin="True" 31 Points="{Binding ElementName=OwnerWindow,Path=Points,Converter={StaticResource pointsC},UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/> 32 </PathFigure.Segments> 33 </PathFigure> 34 </PathGeometry> 35 </Path.Data> 36 </Path> 37 </Grid> 38 39 <StackPanel Grid.Column="1"> 40 <StackPanel> 41 <Label>请输入StartPoint坐标</Label> 42 <StackPanel Orientation="Horizontal"> 43 <Label>X:</Label> 44 <TextBox Width="50" Text="{Binding ElementName=OwnerWindow,Path=XStartPoint,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/> 45 <Label>Y:</Label> 46 <TextBox Width="50" Text="{Binding ElementName=OwnerWindow,Path=YStartPoint,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/> 47 </StackPanel> 48 </StackPanel> 49 <StackPanel> 50 <Label>请输入EndPoint坐标</Label> 51 <StackPanel Orientation="Horizontal"> 52 <Label>X:</Label> 53 <TextBox Width="50" Text="{Binding ElementName=OwnerWindow,Path=XEndPoint,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/> 54 <Label>Y:</Label> 55 <TextBox Width="50" Text="{Binding ElementName=OwnerWindow,Path=YEndPoint,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/> 56 </StackPanel> 57 </StackPanel> 58 <StackPanel> 59 <Label>请输入路线经过的坐标点</Label> 60 <StackPanel Orientation="Horizontal"> 61 <Label>X:</Label> 62 <TextBox Width="50" Text="{Binding ElementName=OwnerWindow,Path=XPoint,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/> 63 <Label>Y:</Label> 64 <TextBox Width="50" Text="{Binding ElementName=OwnerWindow,Path=YPoint,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/> 65 <Button Height="20" Click="Button_Click">增加</Button> 66 </StackPanel> 67 </StackPanel> 68 69 <ListBox Height="100" 70 ItemsSource="{Binding ElementName=OwnerWindow,Path=Points}"/> 71 </StackPanel> 72 </Grid>
1 private ObservableCollection<Point> points = new ObservableCollection<Point>(); 2 3 public ObservableCollection<Point> Points 4 { 5 get { return points; } 6 set{points = value;} 7 } 8 9 10 11 12 13 14 public Point StartPoint 15 { 16 get { return (Point)GetValue(StartPointProperty); } 17 set { SetValue(StartPointProperty, value); } 18 } 19 20 // Using a DependencyProperty as the backing store for StartPoint. This enables animation, styling, binding, etc... 21 public static readonly DependencyProperty StartPointProperty = 22 DependencyProperty.Register("StartPoint", typeof(Point), typeof(PathAnimationDemo), new PropertyMetadata(new Point(0, 0))); 23 24 25 26 public Point EndPoint 27 { 28 get { return (Point)GetValue(EndPointProperty); } 29 set 30 { 31 SetValue(EndPointProperty, value); 32 this.OnPropertyChanged("EndPoint"); 33 } 34 } 35 36 // Using a DependencyProperty as the backing store for EndPoint. This enables animation, styling, binding, etc... 37 public static readonly DependencyProperty EndPointProperty = 38 DependencyProperty.Register("EndPoint", typeof(Point), typeof(PathAnimationDemo), new PropertyMetadata(new Point(100, 100))); 39 40 private double xStartPoint; 41 42 public double XStartPoint 43 { 44 get { return this.StartPoint.X; } 45 set 46 { 47 xStartPoint = value; 48 this.StartPoint = new Point(xStartPoint, this.StartPoint.X); 49 } 50 } 51 52 53 private double yStartPoint; 54 55 public double YStartPoint 56 { 57 get { return this.StartPoint.Y; } 58 set 59 { 60 yStartPoint = value; 61 this.StartPoint = new Point(this.StartPoint.X, yStartPoint); 62 } 63 } 64 65 private double xEndPoint; 66 67 public double XEndPoint 68 { 69 get { return this.EndPoint.X; } 70 set 71 { 72 xEndPoint = value; 73 this.EndPoint = new Point(xEndPoint, this.EndPoint.Y); 74 } 75 } 76 77 private double yEndPoint; 78 79 public double YEndPoint 80 { 81 get { return this.EndPoint.Y; } 82 set 83 { 84 yEndPoint = value; 85 this.EndPoint = new Point(this.EndPoint.X, yEndPoint); 86 } 87 } 88 89 90 private double xPoint; 91 92 public double XPoint 93 { 94 get { return xPoint; } 95 set { xPoint = value; } 96 } 97 98 private double yPoint; 99 100 public double YPoint 101 { 102 get { return yPoint; } 103 set { yPoint = value; } 104 } 105 106 107 108 109 public PathAnimationDemo() 110 { 111 this.SetPoints(this.points); 112 InitializeComponent(); 113 114 } 115 116 private void SetPoints(ObservableCollection<Point> myPointCollection) 117 { 118 points.Add(new Point(50, 100)); 119 myPointCollection.Add(new Point(100, 50)); 120 myPointCollection.Add(new Point(200, 100)); 121 myPointCollection.Add(new Point(100, 200)); 122 myPointCollection.Add(new Point(400, 400)); 123 myPointCollection.Add(new Point(600, 600)); 124 } 125 126 public event PropertyChangedEventHandler PropertyChanged; 127 128 private void OnPropertyChanged(string propertyName) 129 { 130 if (PropertyChanged != null) 131 { 132 PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 133 } 134 } 135 136 private void Button_Click(object sender, RoutedEventArgs e) 137 { 138 this.points.Add(new Point(this.xPoint, this.YPoint)); 139 this.Points = this.points; 140 } 141 142 }