2011-10-15 11 views
5

में यूआई जैसे एक्सवाई कंट्रोलर कैसे बना सकता हूं, मैं इस तरह कुछ ढूंढ रहा हूं।मैं WPF

मुझे माउस के साथ एक्सवाई ग्राफ के अंदर समन्वय खींचने में सक्षम होना चाहिए। समन्वय की स्थिति एक्स और वाई मान निर्धारित करती है।

क्या कोई आसानी से उपलब्ध नियंत्रण है जिसका मैं पुन: उपयोग कर सकता हूं? यदि नहीं, तो मैं एक लिखने के बारे में कैसे जा सकता हूं?

I am looking for something like this

उत्तर

4

मैं इस तरह का कोई नियंत्रण नहीं देखा है, मैं लगता है कि आप यह अपने आप को कोड करने के लिए होगा। लागू करने के लिए यहां कुछ चीज़ें हैं, और मैं केवल ग्राफ भाग के बारे में बात करूंगा। सबसे पहले, आपको इस नियंत्रण को व्यवहार करने के तरीके के बारे में एक चेकलिस्ट परिभाषित करनी चाहिए (यानी माउसबटन नीचे होने पर कर्सर के साथ लाइनें ले जाएं), उसके बाद ... अच्छा है, यह मजेदार हिस्सा है!

EDIT: ठीक है, अब यहां एक मोटा संस्करण है, और जब मैं किसी न किसी कहता हूं, तो मेरा मतलब है। मैंने इसे उपयोगकर्ता नियंत्रण के बजाए विंडो में रखा है, तो आप इसे अपने नियंत्रण में पेस्ट कर सकते हैं। इसमें कई त्रुटियां हैं और इन सभी समस्याओं को ठीक करने के बाद ही उत्पादक रूप से उपयोग किया जाना चाहिए। इसके अलावा, आपको पिक्सेल डिज़ाइन को लचीला/सापेक्ष डिज़ाइन जैसे स्ट्रैच-संरेखण के साथ मिश्रित करते समय सावधान रहना होगा। मैंने विंडो को गैर-आकार बदलने योग्य बनाकर पिक्सेल परिशुद्धता तक सीमित कर दिया।

<Window x:Class="graphedit.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" 
    x:Name="window" 
    MouseMove="Window_MouseMove" 
    Height="400" Width="400" 
    ResizeMode="NoResize"> 
<Canvas x:Name="canvas" 
     HorizontalAlignment="Stretch" 
     VerticalAlignment="Stretch"> 
    <Canvas.Background> 
     <RadialGradientBrush> 
      <GradientStop Color="#333333" Offset="1"></GradientStop> 
      <GradientStop Color="#666666" Offset="0"></GradientStop> 
     </RadialGradientBrush> 
    </Canvas.Background> 
    <Border BorderThickness="0,0,1,1" 
      BorderBrush="White" 
      Margin="0,0,0,0" 
      Width="{Binding Path=Point.X}" 
      Height="{Binding Path=Point.Y}"></Border> 

    <Border BorderThickness="1,1,0,0" 
      BorderBrush="White" 
      Margin="{Binding Path=BottomRightBoxMargin}" 
      Width="{Binding Path=BottomRightBoxDimensions.X}" 
      Height="{Binding Path=BottomRightBoxDimensions.Y}"></Border> 
    <Border BorderThickness="1" 
      BorderBrush="White" 
      Margin="{Binding Path=GripperMargin}" 
      Background="DimGray" 
      CornerRadius="4"    
      Width="10" 
      x:Name="gripper" 
      MouseDown="gripper_MouseDown" 
      MouseUp="gripper_MouseUp" 
      Height="10"></Border> 
    <TextBox Text="{Binding Path=Point.X}" Canvas.Left="174" Canvas.Top="333" Width="42"></TextBox> 
    <TextBox Text="{Binding Path=Point.Y}" Canvas.Left="232" Canvas.Top="333" Width="45"></TextBox> 
    <TextBlock Foreground="White" Canvas.Left="162" Canvas.Top="336">X</TextBlock> 
    <TextBlock Canvas.Left="222" Canvas.Top="336" Foreground="White" Width="13">Y</TextBlock> 
</Canvas> 

कोड-पीछे ऐसा दिखाई देता है:

using System.ComponentModel; 
using System.Windows; 

namespace graphedit 
{ 
/// <summary> 
/// Interaction logic for MainWindow.xaml 
/// </summary> 
public partial class MainWindow : Window, INotifyPropertyChanged 
{ 
    private bool isDragging; 

    private Point mousePositionBeforeMove; 

    private Point point; 

    public Point Point 
    { 
     get { return this.point; } 
     set 
     { 
      this.point = value; 
      this.InvokePropertyChanged(null); 
     } 
    } 

    public Thickness BottomRightBoxMargin 
    { 
     get 
     { 
      Thickness t = new Thickness() 
          { 
           Left = this.Point.X, 
           Top = this.Point.Y 
          }; 
      return t; 
     } 
    } 

    public Thickness GripperMargin 
    { 
     get 
     { 
      Thickness t = new Thickness() 
      { 
       Left = this.Point.X - 5, 
       Top = this.Point.Y - 5 
      }; 
      return t; 
     } 
    } 

    public Point BottomRightBoxDimensions 
    { 
     get 
     { 
      return new Point(this.Width - this.Point.X, 
          this.Height - this.Point.Y); 
     } 
    } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     this.Point = new Point(100, 80); 
     this.DataContext = this; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void InvokePropertyChanged(string name) 
    { 
     PropertyChangedEventArgs args = new PropertyChangedEventArgs(name); 
     PropertyChangedEventHandler handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, args); 
     } 
    } 

    private void gripper_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e) 
    { 
     this.isDragging = true; 
     this.mousePositionBeforeMove = e.GetPosition(this.canvas); 
    } 

    private void gripper_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e) 
    { 
     this.isDragging = false; 
    } 

    private void Window_MouseMove(object sender, System.Windows.Input.MouseEventArgs e) 
    { 
     if(this.isDragging) 
     { 
      Point currentMousePosition = e.GetPosition(this.canvas); 
      double deltaX = currentMousePosition.X - this.mousePositionBeforeMove.X; 
      double deltaY = currentMousePosition.Y - this.mousePositionBeforeMove.Y; 

      double newPointX = (this.Point.X + deltaX < 0 ? 0 : (this.Point.X + deltaX > this.Width ? this.Width : this.Point.X + deltaX)) ; 
      double newPointY = (this.Point.Y + deltaY < 0 ? 0 : (this.Point.Y + deltaY > this.Width ? this.Width : this.Point.Y + deltaY)) ; 

      this.Point = new Point(newPointX,newPointY); 
      this.mousePositionBeforeMove = currentMousePosition; 
     } 
    } 
} 
} 
1

आप चार्टिंग पुस्तकालय DynamicDataDisplay पर एक नज़र हो सकता है। यह माइक्रोसॉफ्ट (afaik) द्वारा एक शोध परियोजना के रूप में बनाई गई एक लाइब्रेरी है और जो कार्यक्षमता आप ढूंढ रहे हैं उसे प्रदान कर सकती है।

सबसे पहले, अपनी परियोजना में DynamicDataDisplay dll का संदर्भ और फिर अपने XAML में निम्नलिखित नाम स्थान बनाने के लिए:

xmlns:d3="http://research.microsoft.com/DynamicDataDisplay/1.0" 

तो फिर तुम XAML करने के लिए एक ChartPlotter वस्तु जोड़ सकते हैं और सब कुछ आप इसे से की जरूरत नहीं है पट्टी (अक्ष, किंवदंती, ...)। माउस को ट्रैक करने के लिए आप CursorCoordinateGraph का उपयोग कर सकते हैं। यदि आप लेआउट आदि को बदलना चाहते हैं, तो आप VerticalRange ऑब्जेक्ट का उपयोग कर सकते हैं।

<d3:ChartPlotter Width="500" Height="300" 
        MainHorizontalAxisVisibility="Collapsed" 
        MainVerticalAxisVisibility="Collapsed" 
        LegendVisibility="Collapsed" NewLegendVisible="False"> 
     <!--This allows you to track the mouse-->  
     <d3:CursorCoordinateGraph x:Name="cursorGraph"/> 
     <!-- this range does nothing more then make the background gray, 
      there are other ways to achieve this too--> 
     <d3:VerticalRange Value1="-300" Value2="300" Fill="Gray"/> 
    </d3:ChartPlotter> 

आप माउस की स्थिति को ट्रैक करना चाहते हैं, तो आप उपयोग कर सकते हैं या तो कोड-पीछे:

Point current = cursorGraph.Position; 

या अपने viewmodel करने के लिए Position संपत्ति बाँध:

<d3:CursorCoordinateGraph x:Name="cursorGraph" Position="{Binding CurrentMousePosition}"/> 

हैं जब आप क्लिक करते हैं तो आप वास्तव में स्थिति को ठीक करना चाहते हैं, मुझे लगता है कि आपको ChartPlotter और सी के लिए ऑनक्लिक या माउसक्लिक ईवेंट हैंडलर में एक नया CursorCoordinateGraph बनाना होगा और सी प्वाइंट को अलग करें और इसे नए ग्राफ के लिए प्रदान करें:

//pseudo code!!! 
mainGraph.DoubleClick += HandleDoubleClick; 

private void HandleDoubleClick(object sender, MouseButtonEventArgs e){ 
    //get position from current graph: 
    var position = cursor.Position; 
    //you have to calculate the "real" position in the chart because 
    //the Point provided by Position is not the real point, but screen coordinates 
    //something like cursor.TranslatePoint(cursor.Position, mainGraph); 
    var newCoord = new CursorCoordinateGraph { Position = position }; 
    mainGraph.Children.Add(newCoord); 
} 

आपके पास ऐसा दिखने के लिए कुछ काम हो सकता है जो आप चाहते हैं। मेरा सुझाव है कि आप कोडेप्लेक्स पेज पर दिए गए नमूने के माध्यम से ब्राउज़ करें और चर्चा पृष्ठ पर नज़र डालें। यह पुस्तकालय बहुत बड़ा है और इसकी कई संभावनाएं हैं, लेकिन हालांकि कुछ वास्तविक दस्तावेज प्रदान करता है ...

आशा है कि यह आपको सही दिशा में इंगित करे!

1

मैंने अपने सरल पुन: प्रयोज्य नियंत्रक कनवस नियंत्रण का डेमो बना दिया है। आशा है इससे आपकी मदद होगी। आप अपने एक्सएएमएल में सभी गुणों को सेट कर सकते हैं।

ControllerCanvas.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Input; 
using System.Windows.Media; 

namespace XYControllerDemo 
{ 
    public class ControllerCanvas : Canvas 
    { 
     #region Dependency Properties 

     public Point Point 
     { 
      get { return (Point)GetValue(PointProperty); } 
      set 
      { 
       if (value.X < 0.0) 
       { 
        value.X = 0.0; 
       } 

       if (value.Y < 0.0) 
       { 
        value.Y = 0.0; 
       } 

       if (value.X > this.ActualWidth) 
       { 
        value.X = this.ActualWidth; 
       } 

       if (value.Y > this.ActualHeight) 
       { 
        value.Y = this.ActualHeight; 
       } 

       SetValue(PointProperty, value); 
      } 
     } 

     public static readonly DependencyProperty PointProperty = 
      DependencyProperty.Register("Point", typeof(Point), typeof(ControllerCanvas), new FrameworkPropertyMetadata(new Point(), 
       FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender)); 

     public Brush ControllerStroke 
     { 
      get { return (Brush)GetValue(ControllerStrokeProperty); } 
      set { SetValue(ControllerStrokeProperty, value); } 
     } 

     public static readonly DependencyProperty ControllerStrokeProperty = 
      DependencyProperty.Register("ControllerStroke", typeof(Brush), typeof(ControllerCanvas), new FrameworkPropertyMetadata(Brushes.Red, 
       FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender)); 

     public double ControllerStrokeThickness 
     { 
      get { return (double)GetValue(ControllerStrokeThicknessProperty); } 
      set { SetValue(ControllerStrokeThicknessProperty, value); } 
     } 

     public static readonly DependencyProperty ControllerStrokeThicknessProperty = 
      DependencyProperty.Register("ControllerStrokeThickness", typeof(double), typeof(ControllerCanvas), new FrameworkPropertyMetadata(1.0, 
       FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender)); 

     public Brush GridStroke 
     { 
      get { return (Brush)GetValue(GridStrokeProperty); } 
      set { SetValue(GridStrokeProperty, value); } 
     } 

     public static readonly DependencyProperty GridStrokeProperty = 
      DependencyProperty.Register("GridStroke", typeof(Brush), typeof(ControllerCanvas), new FrameworkPropertyMetadata(Brushes.LightGray, 
       FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender)); 

     public double GridStrokeThickness 
     { 
      get { return (double)GetValue(GridStrokeThicknessProperty); } 
      set { SetValue(GridStrokeThicknessProperty, value); } 
     } 

     public static readonly DependencyProperty GridStrokeThicknessProperty = 
      DependencyProperty.Register("GridStrokeThickness", typeof(double), typeof(ControllerCanvas), new FrameworkPropertyMetadata(1.0, 
       FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender)); 

     public bool GridVisible 
     { 
      get { return (bool)GetValue(GridVisibleProperty); } 
      set { SetValue(GridVisibleProperty, value); } 
     } 

     public static readonly DependencyProperty GridVisibleProperty = 
      DependencyProperty.Register("GridVisible", typeof(bool), typeof(ControllerCanvas), new FrameworkPropertyMetadata(false, 
       FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender)); 

     public Thickness GridMargin 
     { 
      get { return (Thickness)GetValue(GridMarginProperty); } 
      set { SetValue(GridMarginProperty, value); } 
     } 

     public static readonly DependencyProperty GridMarginProperty = 
      DependencyProperty.Register("GridMargin", typeof(Thickness), typeof(ControllerCanvas), new FrameworkPropertyMetadata(new Thickness(0.0, 0.0, 0.0, 0.0), 
       FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender)); 

     public double GridSize 
     { 
      get { return (double)GetValue(GridSizeProperty); } 
      set { SetValue(GridSizeProperty, value); } 
     } 

     public static readonly DependencyProperty GridSizeProperty = 
      DependencyProperty.Register("GridSize", typeof(double), typeof(ControllerCanvas), new FrameworkPropertyMetadata(30.0, 
       FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender)); 

     #endregion 

     #region Drawing Context 

     Pen penGrid = null; 
     Pen penController = null; 

     Brush previousGridStroke = null; 
     double previousGridStrokeThickness = double.NaN; 
     double penGridHalfThickness = double.NaN; 

     Brush previousControllerStroke = null; 
     double previousControllerStrokeThickness = double.NaN; 
     double penControllerHalfThickness = double.NaN; 

     Point p1 = new Point(); 
     Point p2 = new Point(); 
     Point p3 = new Point(); 
     Point p4 = new Point(); 

     double width = double.NaN; 
     double height = double.NaN; 

     void DrawGrid(DrawingContext dc) 
     { 
      width = this.ActualWidth; 
      height = this.ActualHeight; 

      // draw vertical grid lines 
      for (double y = GridMargin.Top; y <= height - GridMargin.Bottom; y += GridSize) 
      { 
       p1.X = GridMargin.Left; 
       p1.Y = y; 
       p2.X = width - GridMargin.Right; 
       p2.Y = y; 

       GuidelineSet g = new GuidelineSet(); 
       g.GuidelinesX.Add(p1.X + penGridHalfThickness); 
       g.GuidelinesX.Add(p2.X + penGridHalfThickness); 
       g.GuidelinesY.Add(p1.Y + penGridHalfThickness); 
       g.GuidelinesY.Add(p2.Y + penGridHalfThickness); 
       dc.PushGuidelineSet(g); 
       dc.DrawLine(penGrid, p1, p2); 
       dc.Pop(); 
      } 

      // draw horizontal grid lines 
      for (double x = GridMargin.Left; x <= width - GridMargin.Right; x += GridSize) 
      { 
       p1.X = x; 
       p1.Y = GridMargin.Top; 
       p2.X = x; 
       p2.Y = height - GridMargin.Bottom; 

       GuidelineSet g = new GuidelineSet(); 
       g.GuidelinesX.Add(p1.X + penGridHalfThickness); 
       g.GuidelinesX.Add(p2.X + penGridHalfThickness); 
       g.GuidelinesY.Add(p1.Y + penGridHalfThickness); 
       g.GuidelinesY.Add(p2.Y + penGridHalfThickness); 
       dc.PushGuidelineSet(g); 
       dc.DrawLine(penGrid, p1, p2); 
       dc.Pop(); 
      } 
     } 

     void DrawController(DrawingContext dc) 
     { 
      width = this.ActualWidth; 
      height = this.ActualHeight; 

      // draw vertical controller line 
      p1.X = 0.0; 
      p1.Y = Point.Y; 
      p2.X = width; 
      p2.Y = Point.Y; 

      GuidelineSet g1 = new GuidelineSet(); 
      g1.GuidelinesX.Add(p1.X + penControllerHalfThickness); 
      g1.GuidelinesX.Add(p2.X + penControllerHalfThickness); 
      g1.GuidelinesY.Add(p1.Y + penControllerHalfThickness); 
      g1.GuidelinesY.Add(p2.Y + penControllerHalfThickness); 
      dc.PushGuidelineSet(g1); 
      dc.DrawLine(penController, p1, p2); 
      dc.Pop(); 

      // draw horizontal controller line 
      p3.X = Point.X; 
      p3.Y = 0.0; 
      p4.X = Point.X; 
      p4.Y = height; 

      GuidelineSet g2 = new GuidelineSet(); 
      g2.GuidelinesX.Add(p3.X + penControllerHalfThickness); 
      g2.GuidelinesX.Add(p4.X + penControllerHalfThickness); 
      g2.GuidelinesY.Add(p3.Y + penControllerHalfThickness); 
      g2.GuidelinesY.Add(p4.Y + penControllerHalfThickness); 
      dc.PushGuidelineSet(g2); 
      dc.DrawLine(penController, p3, p4); 
      dc.Pop(); 
     } 

     protected override void OnRender(DrawingContext dc) 
     { 
      base.OnRender(dc); 

      // create ord update grid pen 
      if (penGrid == null) 
      { 
       penGrid = new Pen(GridStroke, GridStrokeThickness); 

       previousGridStroke = GridStroke; 
       previousGridStrokeThickness = GridStrokeThickness; 

       penGridHalfThickness = penGrid.Thickness/2.0; 
      } 
      else 
      { 
       if (GridStroke != previousGridStroke || GridStrokeThickness != previousGridStrokeThickness) 
       { 
        previousGridStroke = GridStroke; 
        previousGridStrokeThickness = GridStrokeThickness; 
        penGrid.Brush = GridStroke; 
        penGrid.Thickness = GridStrokeThickness; 

        penGridHalfThickness = penGrid.Thickness/2.0; 
       } 
      } 

      // create ord update controller pen 
      if (penController == null) 
      { 
       penController = new Pen(ControllerStroke, ControllerStrokeThickness); 

       previousControllerStroke = ControllerStroke; 
       previousControllerStrokeThickness = ControllerStrokeThickness; 

       penControllerHalfThickness = penController.Thickness/2.0; 
      } 
      else 
      { 
       if (ControllerStroke != previousControllerStroke || ControllerStrokeThickness != previousControllerStrokeThickness) 
       { 
        previousControllerStroke = ControllerStroke; 
        previousControllerStrokeThickness = ControllerStrokeThickness; 
        penController.Brush = ControllerStroke; 
        penController.Thickness = ControllerStrokeThickness; 

        penControllerHalfThickness = penController.Thickness/2.0; 
       } 
      } 

      // drag grid 
      if (GridVisible) 
      { 
       DrawGrid(dc); 
      } 

      // draw controller 
      DrawController(dc); 
     } 

     #endregion 

     #region Mouse Events 

     protected override void OnMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e) 
     { 
      if (!this.IsMouseCaptured) 
      { 
       this.Point = e.GetPosition(this); 

       this.Cursor = Cursors.Hand; 
       this.CaptureMouse(); 
      } 

      base.OnMouseLeftButtonDown(e); 
     } 

     protected override void OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e) 
     { 
      if (this.IsMouseCaptured) 
      { 
       this.Cursor = Cursors.Arrow; 
       this.ReleaseMouseCapture(); 
      } 

      base.OnMouseLeftButtonUp(e); 
     } 

     protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e) 
     { 
      if (this.IsMouseCaptured) 
      { 
       this.Point = e.GetPosition(this); 
      } 

      base.OnMouseMove(e); 
     } 

     #endregion 
    } 
} 

MainWindow.xaml

<Window x:Class="XYControllerDemo.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:XYControllerDemo" 
     Title="XYControllerDemo" Height="410" Width="680"> 
    <Grid> 

     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="50*"/> 
      <ColumnDefinition Width="50*"/> 
     </Grid.ColumnDefinitions> 

     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="Auto"/> 
     </Grid.RowDefinitions> 

     <local:ControllerCanvas x:Name="controller1" 
           Margin="10" Grid.Column="0" Grid.Row="0" 
           Background="Transparent" Width="300" Height="300" 
           GridMargin="0,0,0,0" GridVisible="True" GridSize="30" 
           GridStroke="LightGray" GridStrokeThickness="1.0" 
           ControllerStroke="Red" ControllerStrokeThickness="1.0" 
           Point="50,50"/> 

     <TextBox Grid.Row="1" Grid.Column="0" Margin="10" Width="100" 
       Text="{Binding ElementName=controller1, Path=Point, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 

     <local:ControllerCanvas x:Name="controller2" 
           Margin="10" Grid.Column="1" Grid.Row="0" 
           Background="Transparent" Width="300" Height="300" 
           GridMargin="0,0,0,0" GridVisible="True" GridSize="30" 
           GridStroke="LightGray" GridStrokeThickness="1.0" 
           ControllerStroke="Blue" ControllerStrokeThickness="1.0" 
           Point="90,250"/> 

     <TextBox Grid.Row="1" Grid.Column="1" Margin="10" Width="100" 
       Text="{Binding ElementName=controller2, Path=Point, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 

    </Grid> 
</Window> 

MainWindow.xaml.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

namespace XYControllerDemo 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 
    } 
}