2012-07-03 104 views
0

我有一個UserControl(InfoControl)中的2個文本框綁定到實現INotifyPropertyChanged的虛擬機中的Point屬性。wpf usercontrol定位不是即時更新,而綁定的TextBox呢

我有另一個UserControl(DesignerControl),它包含一個可拖動的矩形。 Rectangle將其Canvas.Left和Canvas.Bottom綁定到同一VM的ConvPoint屬性。當我拖動我的矩形,ConvPoint VM屬性和文本框中的值立即更新,但是當我拖動我的矩形時,但是當我拖動矩形時,但是當我用新的值更新我的文本框,虛擬機點屬性立即更新,但只有當我再次拖動矩形而不是即時定位矩形。

的代碼有點解釋:

首先,我的ViewModel的position屬性

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的,我的矩形了其在畫布上。

我知道我在虛擬機中的屬性或有點髒,但我不知道其他方式正確執行並管理轉換。

有什麼想法?

回答

0

由於ConvPosition依賴於Position,因此您應該在Position setter中爲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兩個附加屬性將是simpliest解決方案。

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}"> 
+0

aarh這個答案似乎是完美的,但不幸的是,它不工作。 我很迷茫現在... – Julien

+0

我認爲最後一個問題是:[Point](http://msdn.microsoft.com/en-us/library/bk9hwzbw)是一個Structure。它沒有實現INotifyPropertyChanged。使用一個(自己的)類,它可以或者可以在你的類MyVM中創建另外兩個屬性'X'和'Y',它爲每個變化創建一個新的點位置。將文本框綁定到這些。 – LPL

+0

我試過實現INotifyPRopertyChanged的類,那是我的DependencyPoint類,因爲我確實無法傳播我的點值。這就是爲什麼我卡在這裏(對不起,這是一段時間,因爲我堅持這一點,我忘了提及) – Julien