2013-05-26 99 views
1

我創建了一個名爲SimpleText的UserControls,並在我的MainWindow.xaml中引用它。我的SimpleText中唯一的是一個TextBox(稱爲tbox)。在我的MainWindow中有另一個TextBox(稱爲tbox2)。我想要實現的是在這兩個文本框之間有一個雙向綁定。綁定用戶控件的元素

我在這裏讀計算器用來改變內部的東西,你必須在用戶控件(糾正我,如果這不是需要)的代碼聲明一個屬性:

public string MyText 
     { 
      get { return tboxUser.Text; } 
      set { tboxUser.Text = value; } 
     } 

然後我可以訪問MYTEXT從MainWindow.xaml但只能給它「靜態」值:

Window x:Class="WpfApplication11.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfApplication11" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <!-- <local:SimpleText MyText="Hello"/> Works !--> 
     <local:SimpleText MyText="{Binding Text, ElementName=tbox2}"/> <!--Does not work--> 
     <TextBox x:Name="tbox2" Margin="0,200,0,0" Text="Text Box 2" /> 
    </Grid> 
</Window> 

它給了我一個錯誤說這個:

A「綁定」不能在「MYTEXT」 p設定類型'SimpleText'的roperty。 '綁定'只能在DependencyObject的DependencyProperty上設置。

但不幸的是,我在這裏很新手,我不知道如何使MyText成爲DependencyProperty。謝謝。

回答

2
ripped from http://www.andrewdenhertog.com/c/create-dependencyproperty-dependencyobject-5-minutes/ 

public int Age 
    { 
     get { return (int)GetValue(AgeProperty); } //do NOT modify anything in here 
     set { SetValue(AgeProperty, value); } //...or here 
    } 

    // Using a DependencyProperty as the backing store for Age. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty AgeProperty = 
     DependencyProperty.Register(
     "Age", //Must be the same name as the property created above 
     typeof(int), //Must be the same type as the property created above 
     typeof(Person), //Must be the same as the owner class 
     new UIPropertyMetadata(
      0, //default value, must be of the same type as the property 
      new PropertyChangedCallback((s, e) => //A callback that gets executed when the property changed 
      { 
       var source = s as Person; 
       s.DOB_Year = DateTime.Now.Year - s.Age; 
      }))); 

爲你的情況,這將是類似下面(注意frameworkpropertymetadataoptions.bindstwowaybydefault)。其實我沒有測試這一點,所以不知道語法是正確的它的工作原理,但其總體思路

public string MyText 
{ 
    get { return (string)GetValue(MyTextProperty); } //do NOT modify anything in here 
    set { SetValue(MyTextProperty, value); } 
} 

public static readonly DependencyProperty MyTextProperty = DependencyProperty.Register("MyText", typeof(string), typeof(SimpleText), new FrameworkPropertyMetadata(null, 
           FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
           MyTextPropertyChangedCallback)); 

private static void MyTextPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    var source = d as SimpleText; 
    source.MyText = e.NewValue.ToString(); 
} 

更新

我試着用這個簡單的例子重建,發現你是一回事在評論中。 This article提供了更深入的解釋。在文章的底部,它描述了用戶控件的數據上下文是如何從父代繼承的。在編譯時你不會看到錯誤,但是如果你使用turn on wpf tracing for data binding,你會發現輸出控制檯中的數據綁定錯誤。解決方法是調整用戶控件內的數據上下文,這可以通過幾種方法來完成,但最簡單的方法可能是在構造函數中,將數據上下文設置在xaml中的頂層UI元素(網格或堆棧面板或其他)本身。

public SimpleText() 
{ 
    InitializeComponent(); 
    grid.DataContext = this; 
} 
+0

我試過這個,但雖然編譯器拋出沒有錯誤,綁定不起作用。謝謝 – Sturm

+0

我終於可以通過添加DataContext引用和我缺少的其他東西來設置綁定:將我的UserControl XAML文本框綁定到MyText屬性。現在我有一個奇怪的行爲:如果我在MainWindow TextBox(tbox2)中寫入,它會自動更新,但如果我在UserControl文本框(tbox)中寫入,則不會自動更新,我必須單擊另一個文本框才能進行更改。它與INotifyPropertyChanged有關嗎? – Sturm

+0

好的,這是我最後一個問題的解決方案:Text =「{Binding ElementName = miControl,Path = MyText,Mode = TwoWay,UpdateSourceTrigger = PropertyChanged}」。我認爲默認方式是在控件失去焦點時更新(這就是爲什麼當我點擊其他文本框時更新的值)。 – Sturm