我在Usercontrol(InfoControl)中有2个TextBox,它们绑定到实现INotifyPropertyChanged的VM中的Point属性。
我有另一个UserControl(DesignerControl),它包含一个可拖动的矩形。 Rectangle的Canvas.Left和Canvas.Bottom绑定到同一VM的ConvPoint属性。 ConvPoint Property(0 => ActualWidth)是Point Property的转换版本(0 => 1)
当我拖动我的矩形时,ConvPoint VM属性和文本框中的值会立即更新,但是当我使用新值更新文本框时,VM Point属性会立即更新,但只有当我拖动时才会定位矩形矩形,而不是立即。
一些代码来解释:
首先,我的ViewModel的位置属性
public class MyVM : ViewModelBase
{
private DependencyPoint position;
public DependencyPoint Position
{
get { return this.position; }
set
{
this.position = value;
RaisePropertyChanged("Position");
}
}
public DependencyPoint ConvPosition
{
get { return new Point(this.Position.X * MainVM.ActualWidth, this.Position.Y * MainVM.AcutalHeight);}
set
{
Point p = new Point(value.X/MainVM.ActualWidth,value.Y/MainVM.ActualHeight);
this.position = p;
RaisePropertyChanged("ConvPosition");
}
}
}
修改
我正在使用这个类DependencyPoint来通知X和Y属性:
public class DependencyPoint : DependencyObject
{
public enum PointOrder
{
isStartPoint,
isEndPoint,
isPoint1,
isPoint2
}
public DependencyPoint()
{
}
public DependencyPoint(Double x, Double y, PointOrder po)
{
this.X = x;
this.Y = y;
this.Order = po;
}
public DependencyPoint(DependencyPoint point)
{
this.X = point.X;
this.Y = point.Y;
this.Order = point.Order;
}
public DependencyPoint(Point point, PointOrder po)
{
this.X = point.X;
this.Y = point.Y;
this.Order = po;
}
public Point ToPoint()
{
return new Point(this.X, this.Y);
}
public PointOrder Order
{
get { return (PointOrder)GetValue(OrderProperty); }
set { SetValue(OrderProperty, value); }
}
// Using a DependencyProperty as the backing store for Order. This enables animation, styling, binding, etc...
public static readonly DependencyProperty OrderProperty =
DependencyProperty.Register("Order", typeof(PointOrder), typeof(DependencyPoint), new UIPropertyMetadata(null));
public Double X
{
get { return (Double)GetValue(XProperty); }
set { SetValue(XProperty, value); }
}
// Using a DependencyProperty as the backing store for X. This enables animation, styling, binding, etc...
public static readonly DependencyProperty XProperty =
DependencyProperty.Register("X", typeof(Double), typeof(DependencyPoint), new UIPropertyMetadata((double)0.0));
public Double Y
{
get { return (Double)GetValue(YProperty); }
set { SetValue(YProperty, value); }
}
// Using a DependencyProperty as the backing store for Y. This enables animation, styling, binding, etc...
public static readonly DependencyProperty YProperty =
DependencyProperty.Register("Y", typeof(Double), typeof(DependencyPoint), new UIPropertyMetadata((double)0.0));
}
然后在我的InfoControl中:
<Grid Grid.Row="0" DataContext="{Binding Position}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<DockPanel Margin="3,3,0,1" Grid.Row="0" LastChildFill="True">
<TextBlock Foreground="White" Padding="0,3,0,0" Margin="2,0,0,0" DockPanel.Dock="Left" Text="StartPoint.X :"/>
<TextBox FontWeight="DemiBold" Foreground="Black" Background="#efefef" Width="Auto" Margin="7,0,0,0" Text="{Binding X, Converter={StaticResource StDConverter}, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"/>
</DockPanel>
<DockPanel Margin="3,3,0,1" Grid.Row="1" LastChildFill="True">
<TextBlock Foreground="White" Padding="0,3,0,0" Margin="2,0,0,0" DockPanel.Dock="Left" Text="StartPoint.Y :"/>
<TextBox FontWeight="DemiBold" Foreground="Black" Background="#efefef" Width="Auto" Margin="7,0,0,0" Text="{Binding Y, Converter={StaticResource StDConverter}, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"/>
</DockPanel>
</Grid>
在DesignerControl中:
<UserControl>
<Canvas>
<Rectangle x:Name="Point" Width="10" Height="10" Canvas.Bottom="{Binding ConvPosition.Y, Mode=TwoWay}" Canvas.Left="{Binding ConvPosition.X, Mode=TwoWay}" />
</Canvas>
</UserControl>
我可以访问actualWidth,并且我的Rectangle在Canvas中定位良好。
我知道我在VM中的属性或有点脏,但我不知道另一种方法来正确地执行它并管理转换。
任何想法?
答案 0 :(得分:0)
因为ConvPosition取决于位置,你应该在位置设置器中为ConvPosition引发NotificationChanged。
public Point Position
{
get { return this.position; }
set
{
this.position = value;
RaisePropertyChanged("Position");
RaisePropertyChanged("ConvPosition");
}
}
ConvPosition你可以改成这个
public Point ConvPosition
{
get { return new Point(this.Position.X * MainVM.ActualWidth, this.Position.Y * MainVM.AcutalHeight); }
set
{
this.Position = new Point(value.X/MainVM.ActualWidth, value.Y/MainVM.ActualHeight);
}
}
修改强>
我认为MyVM中的另外两个属性是最简单的解决方案。
public double X
{
get { return Position.X; }
set
{
Position = new Point(value, Position.Y);
RaisePropertyChanged("X");
}
}
public double Y
{
get { return Position.Y; }
set
{
Position = new Point(Position.X, value);
RaisePropertyChanged("Y");
}
}
仅更改网格:
<Grid DataContext="{Binding}">